In order to facilitate development, the management class of mutex is generally created, and the lock and unlock class (RALL technology) is created at the same time.
class MutexLock : boost::noncopyable { public: MutexLock() : holder_(0) //Thread holder { MCHECK(pthread_mutex_init(&mutex_, NULL)); //mutex dynamic initialization } ~MutexLock() { assert(holder_ == 0); // no holder MCHECK(pthread_mutex_destroy(&mutex_)); //销毁mutex }
bool isLockedByThisThread() const //Can only be called when locked { return holder_ == CurrentThread::tid(); //Determine whether the holder and the current thread are the same }
void lock() { MCHECK(pthread_mutex_lock(&mutex_)); //上锁 assignHolder(); //Set the holder }
void unlock() { unassignHolder(); //Clear the holder MCHECK(pthread_mutex_unlock(&mutex_)); //解锁 }
pthread_mutex_t* getPthreadMutex() /* non-const */ { return &mutex_; //Get the lock, because the condition variable sometimes needs a lock, so return its address }
private: friend class Condition; //friend class condition variable //After the condition variable is locked, when the wait operation is performed, the thread binding is released to prevent the call from failing when other threads are locked. class UnassignGuard : boost::noncopyable
class MutexLockGuard : boost::noncopyable { public: explicit MutexLockGuard(MutexLock& mutex) : mutex_(mutex) { mutex_.lock(); //Using RALL technology, resources are obtained when constructing, and resources are released when destructing } ~MutexLockGuard() { mutex_.unlock(); }