考虑以下情况
将名称字符串作为参数移动到线程中。
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
结束后被销毁。它仍然是指临时的。我想不是。
编辑: 在评论之后,问题归结为
&#34;在原始调用void start之后(std :: string&amp;&amp; name);具有 返回并在std :: thread的构造函数结束后,在哪里 void run的字符串(std :: string&amp;&amp; name);正在努力? &#34;
最新的演示代码似乎表明,Wrap
退出后,run
引用的对象run
会被销毁。
答案 0 :(得分:1)
Details in the process of constructing a std::thread object
上述帖子中接受的答案澄清了这里的情况。
函数run
引用一个临时文件,在<{strong>完成run
函数后被销毁。
答案 1 :(得分:0)
没有悬空引用,因为std::thread
的构造函数参数被客户端线程复制/移动到某个结构中。然后,新创建的线程将在此结构中的复制/移动对象上运行。
在您的特定情况下,std::string
对象确实已移至所描述的结构中。这是std::string
对象run()
正在进行的工作。当线程完成执行时,它将被正确销毁。