C ++中的Shared_ptr和内存可见性

时间:2019-06-20 04:42:07

标签: c++ multithreading synchronization

如果您在线程A上用shared_ptr堆分配了一个对象,则将shared_ptr复制到另一个线程而无需任何同步。是否可以保证另一个线程看到一个完全构造的对象?

int main(){
    auto sp = std::make_shared<int>(5);
    auto f=std::async(std::launch::async, [sp](){
    std::cout<<*sp;});
}

可以保证打印5张吗?

2 个答案:

答案 0 :(得分:1)

在您的示例中,shared_ptr对象在返回之前 std::async已被复制,因此即使原始shared_ptr在第二个对象之前被销毁了,该对象仍然存在于新线程中线程访问它的副本。

因此,答案是肯定的。您正在传递值,因此是副本。

答案 1 :(得分:0)

正如评论中已经指出的那样,您在上述特定情况下(通过线程arg通过传递给新产生的线程的指针访问堆分配的对象)对此问题question的答复。

现在对于您的follow-up question中描述的情形(通过分配给队列的指针在单独的线程中访问堆分配的对象),由于必须执行队列,因此保证工作线程看到的是“ 5”。以线程安全的方式,内存屏障可确保存储在堆对象中的值的可见性(在您的情况下,互斥锁在后台使用内存屏障)。