在新线程中访问移动的std :: string

时间:2017-04-26 03:54:53

标签: c++ multithreading c++11 move stdthread

考虑以下情况

将名称字符串作为参数移动到线程中。

 void start(std::string&& name) {
        t = std::thread{&ThreadRunner::run, this, std::forward<std::string>(name)};
    }

线程的run函数也采用右值引用。

 void run(std::string&& name) {
        const auto errnum = pthread_setname_np(t.native_handle(), name.c_str());
        if (errnum != 0) {
            std::cout << "ERROR " << std::endl;
        }
    }

线程是通过start函数创建的,如下所示:

  ThreadRunner r;
  r.start(std::string("somename"));

问题是。通过pthread_setname_np在函数run中访问的std :: string是否可能是垃圾,因为当范围结束时临时超出了范围?

Demo 在上面的演示中,call结束后,是否保证somename字符串在函数run中有效?

编辑: Demo with constructors/destructors 问题中的std :: string现在被替换为Wrap以打印所涉及的构造函数。

结果是:(第二个字段是对象的地址,第三个是线程ID)

Constructed 0x7ffc395e0ef0 140605000369984
Move Constructed 0x7ffc395e0e60 140605000369984
Move Constructed 0x177a0a0 140605000369984
Destroyed 0x7ffc395e0e60 140605000369984
Destroyed 0x7ffc395e0ef0 140605000369984
Call ended

somename
Destroyed 0x177a0a0 140604983461632

最后一个对象在run结束后被销毁。它仍然是指临时的。我想不是。

A more clean example

编辑: 在评论之后,问题归结为

  

&#34;在原始调用void start之后(std :: string&amp;&amp; name);具有   返回并在std :: thread的构造函数结束后,在哪里   void run的字符串(std :: string&amp;&amp; name);正在努力? &#34;

最新的演示代码似乎表明,Wrap退出后,run引用的对象run会被销毁。

2 个答案:

答案 0 :(得分:1)

Details in the process of constructing a std::thread object

上述帖子中接受的答案澄清了这里的情况。 函数run引用一个临时文件,在<{strong>完成run函数后被销毁。

答案 1 :(得分:0)

没有悬空引用,因为std::thread的构造函数参数被客户端线程复制/移动到某个结构中。然后,新创建的线程将在此结构中的复制/移动对象上运行。

在您的特定情况下,std::string对象确实已移至所描述的结构中。这是std::string对象run()正在进行的工作。当线程完成执行时,它将被正确销毁。