在新线程中访问移动的 std::string
Accessing a moved std::string in a new thread
考虑下面的案例
名称字符串作为参数移至线程。
void start(std::string&& name) {
t = std::thread{&ThreadRunner::run, this, std::forward<std::string>(name)};
}
线程的 运行 函数也采用右值引用。
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;
}
}
线程是通过启动函数创建的,如下所示:
ThreadRunner r;
r.start(std::string("somename"));
问题是。是否有可能通过 pthread_setname_np 在函数 run
中访问的 std::string 可能是垃圾,因为临时对象在范围结束时超出了范围?
Demo
上面的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
结束后销毁。它是否仍然指的是临时的。我觉得不是。
编辑:
评论后,问题归结为
"After the original call to void start(std::string&& name); has
returned and after the constructor of std::thread has ended, where is
the string that void run(std::string&& name); is working on? "
最新的演示代码似乎显示 run
引用的对象 Wrap
在 run
退出后被销毁。
上面post中接受的答案澄清了这里的情况。
函数 run
引用了一个临时对象,该临时对象在 run
函数完成后 被销毁。
没有悬挂引用,因为 std::thread
的构造函数参数被客户端线程 copied/moved 放入某个结构中。然后,新创建的线程将在该结构中的 copied/moved 个对象上 运行。
在您的特定情况下,std::string
对象确实已移入所描述的结构中。那是 std::string
对象 run()
正在处理的。当线程完成执行时,它将被适当地销毁。
考虑下面的案例
名称字符串作为参数移至线程。
void start(std::string&& name) {
t = std::thread{&ThreadRunner::run, this, std::forward<std::string>(name)};
}
线程的 运行 函数也采用右值引用。
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;
}
}
线程是通过启动函数创建的,如下所示:
ThreadRunner r;
r.start(std::string("somename"));
问题是。是否有可能通过 pthread_setname_np 在函数 run
中访问的 std::string 可能是垃圾,因为临时对象在范围结束时超出了范围?
Demo
上面的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
结束后销毁。它是否仍然指的是临时的。我觉得不是。
编辑: 评论后,问题归结为
"After the original call to void start(std::string&& name); has returned and after the constructor of std::thread has ended, where is the string that void run(std::string&& name); is working on? "
最新的演示代码似乎显示 run
引用的对象 Wrap
在 run
退出后被销毁。
上面post中接受的答案澄清了这里的情况。
函数 run
引用了一个临时对象,该临时对象在 run
函数完成后 被销毁。
没有悬挂引用,因为 std::thread
的构造函数参数被客户端线程 copied/moved 放入某个结构中。然后,新创建的线程将在该结构中的 copied/moved 个对象上 运行。
在您的特定情况下,std::string
对象确实已移入所描述的结构中。那是 std::string
对象 run()
正在处理的。当线程完成执行时,它将被适当地销毁。