【问题标题】:Create object in thread A, use in thread B. Mutex required?在线程 A 中创建对象,在线程 B 中使用。需要互斥锁吗?
【发布时间】:2018-02-12 10:48:49
【问题描述】:

我一直在阅读有关多线程、C++、正确同步和防止竞争条件的锁的不同内容。但是,我没有回答一个问题: 如果我在线程 A 中创建了一个对象,但之后只在线程 B 中使用它,是否需要互斥锁?

换句话说,我知道我不需要互斥锁来防止竞争条件 - 我是否需要互斥锁来充当内存屏障(或其他潜在问题)?

一个非常基本的例子来形象化我的意思

struct Object {
    void do_stuff();
};

Object o;
std::thread worker_thread([&o](){
    while (alive)
        o.do_stuff();
}).join();
// `o` is never used outside worker_thread

如果您还可以向我推荐一些文章/书籍,我会很高兴我可以阅读更多有关该主题和/或正确的关键字来搜索这些场景。

【问题讨论】:

  • 如果只有一个线程在使用该对象,你可以指望它,那么你应该没有问题。

标签: c++ multithreading mutex


【解决方案1】:

这很好,您不需要mutex

创建线程会设置内存屏障,因此通过您传递给worker_thread 的引用访问o 是安全的。

§ 30.3.2.2-6 - [thread.thread.constr]

构造函数调用的完成与f副本调用的开始同步。

虽然worker_thread 正在运行,但显然您可能无法在创建它的线程中访问o(如您所说)。

加入线程也会设置障碍,因此在worker_thread 加入后,您可以在主线程中再次访问o

§ 30.3.2.5-4 - [thread.thread.destr]

*this 表示的线程的完成与 (1.10) 对应的成功 join() 返回同步。

进一步阅读:

  • Anthony Williams 写了一本关于并行编程的好书(C++ 并发
  • Bjarne Stroustrup 的书(C++ 编程语言,第 4 版)有两个关于并发编程的精彩章节。
  • Jeff Preshing 有一篇关于这些主题的不错的博客;查看 preshing.com

【讨论】:

  • 完美,非常感谢。我实际上正在阅读 C++ concurrency in action,但找不到这些信息。但我想那是因为我没有在脑海中建立线程创建和内存屏障之间的联系
  • 欢迎......有时很难找到共同点,因为这些是不同的主题,通常在不同的章节中涉及
猜你喜欢
  • 2013-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-16
  • 2012-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多