如果您在线程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张吗?
答案 0 :(得分:1)
在您的示例中,shared_ptr
对象在返回之前 std::async
已被复制,因此即使原始shared_ptr在第二个对象之前被销毁了,该对象仍然存在于新线程中线程访问它的副本。
因此,答案是肯定的。您正在传递值,因此是副本。
答案 1 :(得分:0)
正如评论中已经指出的那样,您在上述特定情况下(通过线程arg通过传递给新产生的线程的指针访问堆分配的对象)对此问题question的答复。
现在对于您的follow-up question中描述的情形(通过分配给队列的指针在单独的线程中访问堆分配的对象),由于必须执行队列,因此保证工作线程看到的是“ 5”。以线程安全的方式,内存屏障可确保存储在堆对象中的值的可见性(在您的情况下,互斥锁在后台使用内存屏障)。