The encapsulation of the C ++ thread lock mainly provides operations such as lock, unlock, and require. Note that the thread repeatedly acquires the lock and sets a count counter, this calculator does not consider the atomic operations of ++ and -- because the counter itself is in lock and unlock, so it is thread-safe.
In addition, mutable count prevents the count change operation from being performed in the const method to ensure the method semantics.
Class tc_threadcond;/*** thread mutex object */struct tc_threadmutex_exception: Public tc_lock_exception {tc_threadmutex_exception (const string & buffer): tc_lock_exception (buffer) {}; terminate (const string & buffer, int ERR): tc_lock_exception (buffer, err ){};~ Tc_threadmutex_exception () Throw () {};};/*** thread lock */class tc_threadmutex {public: tc_threadmutex (); Virtual ~ Tc_threadmutex ();/*** lock */void lock () const;/*** try to lock ** @ return bool */bool trylock () const; /*** unlock */void unlock () const;/*** unlock the lock and call unlock to determine whether unlock will be unlocked, * always return true ** @ return bool */bool willunlock () const {return true;} protected: // noncopyable tc_threadmutex (const tc_threadmutex &); void operator = (const tc_threadmutex &);/*** count */INT count () const;/*** count */void count (I NT c) const; friend class tc_threadcond; protected: mutable pthread_mutex_t _ mutex ;};/*** thread lock class * using thread library implementation **/class tc_threadrecmutex {public: /*** constructor */tc_threadrecmutex ();/*** analyze enough functions */virtual ~ Tc_threadrecmutex ();/*** lock, call pthread_mutex_lock * return: return the return value of pthread_mutex_lock */INT lock () const;/*** unlock, pthread_mutex_unlock * return: returns the return value of pthread_mutex_lock */INT unlock () const;/*** attempts to lock. If the lock fails, an exception is thrown. * return: True, the lock is successful; false other threads have locked */bool trylock () const;/*** call unlock to unlock the lock, ** @ return bool */bool willunlock () const used by tc_monitor; protected:/*** youyuan class */friend class tc_threadcond; /***** count */INT count () const;/***** count */void count (INT c) const; private: /** Lock Object */mutable pthread_mutex_t _ mutex; mutable int _ count ;};
TC_ThreadMutex::TC_ThreadMutex(){ int rc; pthread_mutexattr_t attr; rc = pthread_mutexattr_init(&attr); assert(rc == 0); rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); assert(rc == 0); rc = pthread_mutex_init(&_mutex, &attr); assert(rc == 0); rc = pthread_mutexattr_destroy(&attr); assert(rc == 0); if(rc != 0) {xxx throw TC_ThreadMutex_Exception("[TC_ThreadMutex::TC_ThreadMutex] pthread_mutexattr_init error", rc); }}TC_ThreadMutex::~TC_ThreadMutex(){ int rc = 0; rc = pthread_mutex_destroy(&_mutex); assert(rc == 0);}void TC_ThreadMutex::lock() const{ int rc = pthread_mutex_lock(&_mutex); if(rc != 0) { if(rc == EDEADLK) { throw TC_ThreadMutex_Exception("[TC_ThreadMutex::lock] pthread_mutex_lock dead lock error", rc); } else { throw TC_ThreadMutex_Exception("[TC_ThreadMutex::lock] pthread_mutex_lock error", rc); } }}bool TC_ThreadMutex::tryLock() const{ int rc = pthread_mutex_trylock(&_mutex); if(rc != 0 && rc != EBUSY) { if(rc == EDEADLK) { throw TC_ThreadMutex_Exception("[TC_ThreadMutex::tryLock] pthread_mutex_trylock dead lock error", rc); } else { throw TC_ThreadMutex_Exception("[TC_ThreadMutex::tryLock] pthread_mutex_trylock error", rc); } } return (rc == 0);}void TC_ThreadMutex::unlock() const{ int rc = pthread_mutex_unlock(&_mutex); if(rc != 0) { throw TC_ThreadMutex_Exception("[TC_ThreadMutex::unlock] pthread_mutex_unlock error", rc); }}int TC_ThreadMutex::count() const{ return 0;}void TC_ThreadMutex::count(int c) const{}///////////////////////////////////////////////////////////////////////////////////////////////////////////////////TC_ThreadRecMutex::TC_ThreadRecMutex(): _count(0){ int rc; pthread_mutexattr_t attr; rc = pthread_mutexattr_init(&attr); if(rc != 0) {throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::TC_ThreadRecMutex] pthread_mutexattr_init error", rc); } rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); if(rc != 0) {throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::TC_ThreadRecMutex] pthread_mutexattr_settype error", rc); } rc = pthread_mutex_init(&_mutex, &attr); if(rc != 0) {throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::TC_ThreadRecMutex] pthread_mutex_init error", rc); } rc = pthread_mutexattr_destroy(&attr); if(rc != 0) {throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::TC_ThreadRecMutex] pthread_mutexattr_destroy error", rc); }}TC_ThreadRecMutex::~TC_ThreadRecMutex(){while (_count){unlock();} int rc = 0; rc = pthread_mutex_destroy(&_mutex); assert(rc == 0);}int TC_ThreadRecMutex::lock() const{ int rc = pthread_mutex_lock(&_mutex); if(rc != 0) {throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::lock] pthread_mutex_lock error", rc); } if(++_count > 1) {rc = pthread_mutex_unlock(&_mutex);assert(rc == 0); }return rc;}int TC_ThreadRecMutex::unlock() const{ if(--_count == 0) {int rc = 0;rc = pthread_mutex_unlock(&_mutex);return rc; }return 0;}bool TC_ThreadRecMutex::tryLock() const{ int rc = pthread_mutex_trylock(&_mutex); if(rc != 0 ) {if(rc != EBUSY){throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::tryLock] pthread_mutex_trylock error", rc);} } else if(++_count > 1) { rc = pthread_mutex_unlock(&_mutex); if(rc != 0) { throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::tryLock] pthread_mutex_unlock error", rc); } } return (rc == 0);}bool TC_ThreadRecMutex::willUnlock() const{ return _count == 1;}int TC_ThreadRecMutex::count() const{ int c = _count; _count = 0; return c;}void TC_ThreadRecMutex::count(int c) const{ _count = c;}