在新线程中访问移动的 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 结束后销毁。它是否仍然指的是临时的。我觉得不是。

A more clean example

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

"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 引用的对象 Wraprun 退出后被销毁。

上面post中接受的答案澄清了这里的情况。 函数 run 引用了一个临时对象,该临时对象在 run 函数完成后 被销毁。

没有悬挂引用,因为 std::thread 的构造函数参数被客户端线程 copied/moved 放入某个结构中。然后,新创建的线程将在该结构中的 copied/moved 个对象上 运行。

在您的特定情况下,std::string 对象确实已移入所描述的结构中。那是 std::string 对象 run() 正在处理的。当线程完成执行时,它将被适当地销毁。