webRTC base模块CritScope临界锁的实现

来源:互联网 发布:2016小说改编的网络剧 编辑:程序博客网 时间:2024/06/09 16:49

CritCal临界锁的实现

Linux下临界锁的实现

使用posix线程接口实现
实现文件: webRTC/base/critcalsection.h

暴露给外部使用的类CritScope

class SCOPED_LOCKABLE CritScope { public:  explicit CritScope(const CriticalSection* cs) EXCLUSIVE_LOCK_FUNCTION(cs);  ~CritScope() UNLOCK_FUNCTION(); private:  const CriticalSection* const cs_;  RTC_DISALLOW_COPY_AND_ASSIGN(CritScope);};CritScope::CritScope(const CriticalSection* cs) : cs_(cs) { cs_->Enter(); }CritScope::~CritScope() { cs_->Leave(); }

CritScope很明显是封装了CritcalSection类
从实现细节上可以推断出调用方法应该是这样的

crit是调用类的private私有变量调用类的某个方法内xx_class::xx_method {    {        CritScope crit(&crit_);        ....    }    ....}

构造时初始化和进入临界区 析构时退出临界区 典型的C++写法

CriticalSection的实现

Linux下采用pthread_mutex实现

mutex属性设置

CriticalSection::CriticalSection() {#if defined(WEBRTC_WIN)  InitializeCriticalSection(&crit_);#else#if defined(WEBRTC_MAC) && !USE_NATIVE_MUTEX_ON_MAC  lock_queue_ = 0;  owning_thread_ = 0;  recursion_ = 0;  semaphore_ = dispatch_semaphore_create(0);#else  pthread_mutexattr_t mutex_attribute;  pthread_mutexattr_init(&mutex_attribute);  pthread_mutexattr_settype(&mutex_attribute, PTHREAD_MUTEX_RECURSIVE);  pthread_mutex_init(&mutex_, &mutex_attribute);  pthread_mutexattr_destroy(&mutex_attribute);#endif  CS_DEBUG_CODE(thread_ = 0);  CS_DEBUG_CODE(recursion_count_ = 0);#endif}

构造方法中,将锁的属性设置为了PTHREAD_MUTEX_RECURSIVE
设置RECURSIVE后,线程锁将可以重复的获得而不会阻塞
通俗的说就是
默认的设置下 锁lock后必须unlock 才能再次lock
设置RECURSIVE后 锁lock后即使没有unlock 也可以成功再次lock

原理就是设置RECURSIVE后 锁会进行lock的计数 lock和unlock的数目对应后 其他线程才能获得锁

举个例子 如果用有一个socket链表需要维护
链表类有两个操作 add和delect
socket链表表示是一个缓冲区buffer 那么udp接收线程可以访问它 tcp接收线程也可以(也可以是有多个udp接收线程) 此时必须等待所有add操作都结束了才能进行delete
这就是互斥锁的属性设置为RECURSIVE的意义

CritScope和TryCritScope的意义就在于做共享资源的临界保护 防止同时操作引起错误

也就分别对于posix接口的pthread_mutex_lock和pthread_mutex_trylock

测试代码git地址

https://github.com/sliver-chen/webRTCTutorial/blob/master/CritScope/CritTest.cpp

原创粉丝点击