将std :: sub_match作为参数传递给std :: thread时出了什么问题?

马库斯·R。

我将astd::sub_match作为参数传递给a std::thread(请参见下面的示例代码)。线程函数需要一个const字符串引用。sub_match可以转换为字符串。所以一切都编译良好。

但是有时函数会收到错误的字符串。当我在将sub_match传递给线程之前将其转换为字符串时,它可以按预期工作。有什么不同?

我认为这是一个竞争条件,因为线程执行时原始的sub_match可能不再存在。但是我认为线程的参数还是会被复制。我如何找出哪些参数可以安全地传递给线程,哪些不可以?

#include <iostream>
#include <string>
#include <vector>
#include <thread>
#include <regex>
#include <unistd.h>

class test_t {
  public:
    test_t(void) {}
    ~test_t(void) {}

    void start(void){
     //-------------------------------------------------
     // Do some memory allocation.
     // The error seems to appear faster with that.
     std::vector<std::string> vec;
     for(unsigned int i = 0; i < 1000; ++i) {
        vec.push_back("test_test_test");
     }
     //-------------------------------------------------

     std::string event = "operating";
     std::smatch match;
     std::regex expr("\\(operating\\)",
         std::regex_constants::icase | 
         std::regex_constants::basic);

     if(std::regex_match(event, match, expr)) {
        std::cout << "start thread" << std::endl;
        m_thread = std::thread(&test_t::thread_func, this, match[1]);              //NOK
//        m_thread = std::thread(&test_t::thread_func, this, match[1].str());        // OK
//        m_thread = std::thread(&test_t::thread_func, this, (std::string)match[1]); // OK
        m_thread.detach();
        std::cout << "thread started" << std::endl;
     }
    }

  private:
    std::thread m_thread;

    void thread_func(const std::string& string) {
     if(string != "operating") {
        std::cout << "ERROR: string: \"" << string << "\"" << std::endl;
        exit(EXIT_FAILURE);
     } else {
        std::cout << "string: \"" << string << "\"" << std::endl;
     }
    }
};

int main(int argc, char** argv) {
  test_t test;
  while(1) {
    test.start();
    usleep(100);
  }
  return 0;
}

编译消息:

Compiled with: g++ --std=c++11 -pthread -o test main.cpp
g++ --version: g++ (SUSE Linux) 4.8.5

预期产量:

start thread
thread started
string: "operating"
(repeat)

实际输出:

start thread
thread started
string: "operating"
ERROR: string: "test_test"
rafix07

operator[]对于可以视为匹配字符的迭代器对的std::smatch返回sub_match

之后regex_match被调用,您可以使用operator[],只要访问子匹配event存在。event被删除时(您没有加入线程,因此会start立即返回并被event销毁),子匹配项具有悬空的指针,不应访问。


m_thread = std::thread(&test_t::thread_func, this, match[1]);

这是行不通的,因为当函数超出范围时,事件将被删除并且子匹配项具有悬空的指针。


m_thread = std::thread(&test_t::thread_func, this, match[1].str());

之所以有效,是因为str()返回匹配字符串的副本。


m_thread = std::thread(&test_t::thread_func, this, (std::string)match[1]);

这也是有效的,因为根据sub-match创建了临时字符串match[1],并将temp传递给了线程。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

将参数传递给std :: thread的区别,C ++

将参数传递给std :: thread包装器

将模板args传递给std :: thread

指向对象的指针作为参数传递给std :: thread时的内存可见性

将(迭代器)值传递给闭包(预期类型参数`I`,找到结构`std::slice::Iter`)有什么问题?

将 std::function 作为参数传递给 const void *

为什么我们不允许将纯引用参数传递给std :: thread但允许传递原始指针?

为什么std :: bind静态地将类型检查参数传递给函数?

为什么不能使用模板模板参数将std :: vector <MyType>传递给此函数?

分配数组时是否可以将参数传递给std :: make_unique()?

将lambda传递给可变参数std :: function时的类型推断

为什么`std :: pair`将`std :: tuple`作为ctor参数类型而不是`const std :: tuple&`?

是否可以将重载方法传递给std :: thread

将类的成员函数传递给std :: thread

将lambda作为std :: function的参数传递时,C ++候选模板被忽略的错误

在结构列表上调用 std::sort 时将 const 作为“this”参数错误传递

将std :: vector作为模板模板参数传递时出错-在GCC中工作,在MSVC中失败

将std :: function *传递给模板参数

将std :: unique_ptr传递给类时出错

为什么在声明使用命名空间std时将int用作指针参数传递给函数?

将 std::left 作为参数传递

无法将Callable作为参数启动C ++ std :: thread

Boost sub_match引发std :: length_error异常

将std :: unique_ptr重置为数组指针有什么问题?

将std :: shared_ptr传递给函数对象到std :: thread

将标志作为位置参数传递给re.sub时,Python正则表达式不起作用

将左值传递给用作临时std容器的模板参数的通用引用参数时与分配器相关的错误

如何将可变参数传递给std :: thread?

将函数直接传递给std :: async和使用std :: bind有什么区别?