unique_ptr线程安全吗?

Val*_*lea 26 c++ multithreading thread-safety unique-ptr c++11

unique_ptr线程安全吗?以下代码是否无法两次打印相同的数字?

#include <memory>
#include <string>
#include <thread>
#include <cstdio>

using namespace std;

int main()
{
    unique_ptr<int> work;

    thread t1([&] {
        while (true) {
            const unique_ptr<int> localWork = move(work);
            if (localWork)
                printf("thread1: %d\n", *localWork);
            this_thread::yield();
        }
    });

    thread t2([&] {
        while (true) {
            const unique_ptr<int> localWork = move(work);
            if (localWork)
                printf("thread2: %d\n", *localWork);
            this_thread::yield();
        }
    });

    for (int i = 0; ; i++) {
        work.reset(new int(i));

        while (work)
            this_thread::yield();
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Bar*_*ski 35

如果使用正确,unique_ptr是线程安全的.你打破了不成文的规则:你永远不会通过引用传递线程之间的unique_ptr.

unique_ptr背后的理念是它始终拥有一个(唯一的)所有者.因此,您可以始终在线程之间安全地传递它而不进行同步 - 但您必须按值传递它,而不是通过引用传递它.为unique_ptr创建别名后,您将失去唯一性属性,并且所有赌注均已关闭.不幸的是,C++不能保证唯一性,所以你要留下一个你必须遵循的惯例.不要为unique_ptr创建别名!

  • 你确定吗?我内心的偏执狂程序员告诉我,如果您在线程之间传递up,则它是UB,因为您不确保seq_cst,也就是如果上行指向的内容被线程1修改,然后up传递给线程2,那么线程2可能会看到过时的值。指向东西。 (2认同)
  • -1. 当人们询问线程安全时,他们实际上是在问同时从多个线程访问一个对象的**一个实例**是否安全。从这个意义上说,`unique_ptr` 并不比 `T*` 安全。 (2认同)
  • 这个答案没有任何意义。你_不能_按值传递`unique_ptr`。 (2认同)

Use*_*ess 23

不,它不是线程安全的.

两个线程都可能move没有显式同步的工作指针,因此两个线程可能获得相同的值,或者两者都获得一些无效的指针...它是未定义的行为.

如果你想正确地做这样的事情,你可能需要使用类似的东西,std::atomic_exchange因此两个线程都可以用正确的语义读取/修改共享工作指针.


Sin*_*all 9

根据Msdn:

以下线程安全规则适用于标准C++库中的所有类(shared_ptr和iostream类除外,如下所述).

单个对象对于从多个线程读取是线程安全的.例如,给定对象A,可以安全地从线程1和线程2同时读取A.

如果一个线程正在写入单个对象,则必须保护对相同或其他线程上该对象的所有读写操作.例如,给定对象A,如果线程1写入A,则必须阻止线程2读取或写入A.

即使另一个线程正在读取或写入同一类型的不同实例,也可以安全地读取和写入一个类型的实例.例如,给定相同类型的对象A和B,如果在线程1中写入A并且在线程2中读取B,则是安全的.