微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

std::thread 参数被复制到新线程上?

如何解决std::thread 参数被复制到新线程上?

我已经开始阅读 Anthony Williams 的“C++ Concurrency in action,seconds edition”。在其 2.2 部分中,他写道线程函数的参数被复制到新线程上。我在几个编译器上检查了这一点,这是真的:如果我们传递一个左值 - 它会被复制到新线程上。

Anthony 写道,这可能代表未定义的行为 - 当新线程启动时,左值可能会超出原始范围的范围。

这有点吓人。这是否意味着每个 std::thread 构造函数调用都有潜在的竞争?为什么这种复制在从 std::thread 构造函数返回之前不同步?为什么它没有完全复制到原始线程上?

解决方法

来自:std::thread::thread

除了在调用者的上下文中评估对decay_copy的调用,因此在评估和复制/移动参数期间抛出的任何异常都会在当前线程中抛出,而不会启动新线程。 构造函数调用的完成与(在 std::memory_order 中定义)在新的执行线程上调用 f 的副本的开始同步。

这描述了所有复制操作都在线程开始执行之前完成。

但是让我们测试一下!

如果我们运行这个简短的例子:

class CopyMe
{
    private:
        std::string s;
    public:
        CopyMe() = default;
        CopyMe( const CopyMe& ) { std::cout << "CATCH Copy Me" << std::endl; }
        CopyMe( CopyMe&& ) { std::cout << "CATCH Moved" << std::endl; }
        CopyMe( const char* s_ ):s{s_}{ std::cout << "CATCH Implicit conversion" << std::endl; }
};

void Run( CopyMe )
{
    std::cout << "CATCH Thread context" << std::endl; 
}


int main()
{
    std::cout << "CATCH Main Context" << std::endl;
    CopyMe me; 
    std::thread t( Run,"Hallo");
    t.join();
}

带有strace -xfo dump prog

和 grep 对于我们的输出,我们得到:

6071  write(1,"CATCH Main Context\n",19) = 19
6072  write(1,"CATCH Implicit conversion\n",26) = 26
6072  write(1,"CATCH Thread context\n",21) = 21

乌布斯!我们看到隐式转换的部分是在新创建的线程内部完成的!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。