webrtc关于锁的编程思想

来源:互联网 发布:俄罗斯女孩中国人知乎 编辑:程序博客网 时间:2024/05/18 02:37

如何使用锁很简单,但是如何用好锁就很困难了,当线程很多的时候总是由于自己忘记了初始化,忘记了调用解锁,或者由于程序异常而出现没有正常解锁的情况,导致庞大的程序出现各种问题,最常见的就是死了,而不是崩溃了。

下面根据我看到的webrtc代码,将webrtc的思想抽出来分享给大家,原来我曾在c++程序设计语言看到过这种思想,但是一直没当回事,感觉太小case了,大的项目谁会这样用,多写了多少代码呀。

主要有两个东西:

1,scopted_ptr,这个我前面介绍过

2,局部对象管理资源,实际上也介绍过。仍然类似于栈管理堆的思想。


有一个锁类CriticalSectionWrapper,见上文的webrtc的锁,它有一个工厂方法创建一个锁,返回指向锁的指针。

方法1:

class MyClass{private:CriticalSectionWrapper* critsec;}void MyClass::FuncNeedToHaveLock(){critsec->Enter();//.....codecritsec->Leave();}


critsec这个锁指针会在MyClass类的构造函数分配内存,析构函数释放内存。

方法二:

对于堆资源的管理,可以采用智能指针,它都是利用了一个栈上的对象去管理一个堆上的对象,从而使得堆上的对象随着栈上的对象销毁时自动删除。

我们的代码应该会变成这样

class MyClass{private:scopted_ptr<CriticalSectionWrapper> callback_cs_}MyClass::MyClass():callback_cs_(CriticalSectionWrapper::CreateCriticalSection()){}void MyClass::FuncNeedToHaveLock(){callback_cs_->Enter();//.....codecallback_cs_->Leave();}


但如果FuncNeedToHaveLock的code出现异常,或者是有很多的退出点,而忘记了在每一个退出点都调用Leave方法,那就会出现问题,一个更好的解决办法还是栈内存管理资源的思想。

方法三:

先声明一个类

class CriticalSectionScoped { public:  explicit CriticalSectionScoped(CriticalSectionWrapper* critsec)    : ptr_crit_sec_(critsec) {    ptr_crit_sec_->Enter();  }  ~CriticalSectionScoped() {    if (ptr_crit_sec_) {      Leave();    }  } private:  void Leave() {    ptr_crit_sec_->Leave();    ptr_crit_sec_ = 0;  }  CriticalSectionWrapper* ptr_crit_sec_;};
它构造函数加锁,析构函数解锁,于是在FuncNeedToHaveLock函数中,我们可以这样写:

void MyClass::FuncNeedToHaveLock(){CriticalSectionScoped cs(callback_cs_.get());//.....code}
这样就可以保证正常的管理锁的Enter和Leave的一致性,还可以很好的管理锁的内存。
非常好的思想,在c++程序设计语言中都有体现,只是我有点目不识珠了,以后采纳!!!。



原创粉丝点击