说说shared_ptr“线程安全性,原理”

在多线程的编译环境中,调用不同shared_ptr实例的成员函数是不需要额外的同步手段的,即使这些shared_ptr拥有的是同样的对象。

但是如果多线程“访问(有写操作)”同一个shared_ptr,则需要同步,否则就会有race condition发生。也可以使用shared_ptr overloads of atomic functions来防止race condition的发生。

多个线程同时同一个shared_ptr对象是线程安全的,但是,如果是多个线程对同一个shared_ptr对象进行读和写,则需要加锁。

多线程读写shared_ptr所指向的同一个对象,
不管是相同的shared_ptr对象,还是不同的shared_ptr对象,都需要加锁保护。

eg:

shared_ptr<long>global_instance=make_shared<long>(0);
std::mutex g_i_mutex;void thread_fcn() 
{
//std::lock_guard<std::mutex>lock(g_i_mutex);
//shared_ptr<long>local=global_instance;    
   for(int i=0; i<100000000; i++)    
   {        
      *global_instance = *global_instance + 1;        //*local=*local+1;    
   }
}
void main() {    
  thread thread1(thread_fcn);    
  thread thread2(thread_fcn);                
  thread1.join();    
  thread2.join();      
  cout<<"*global_instance is"<<*global_instance;
}

在线程函数thread_fcn的for循环中,2个线程同时对global_instance进行加1的操作。这就是典型的非线程安全的场景,最后的结果是未定的,
运行结果为:*global_instance is197240539;

如果使用的是每个线程的局部shared_ptr对象local,因为这些local指向相同的对象,因此结果也是未定的,
运行结果为:*global_instance is160285803;

因此,这种情况下必须加锁,将thread_fcn中的第一行代码的注释去掉之后,不管是使用global_instance,还是使用local,
得到的结果都是:*global_instance is 200000000

#include <iostream>
#include <memory>
using namespace std;

int main()
{
    shared_ptr<int> sp1(new int(100));
    cout << "当前计数: " << sp1.use_count() << endl;//1
    auto sp2 = sp1;
    cout << "当前计数: " << sp1.use_count() << endl;//2
    {
        auto sp3 = sp2;
        cout << "当前计数: " << sp1.use_count() << endl;//3
    }
    cout << "当前计数: " << sp1.use_count() << endl;//2
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

踏过山河,踏过海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值