muduo之mutex和condition
生活随笔
收集整理的這篇文章主要介紹了
muduo之mutex和condition
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
? ? ? ? 線程同步所需的mutex和condition,記錄一下。
Mutex.h
// Use of this source code is governed by a BSD-style license // that can be found in the License file. // // Author: Shuo Chen (chenshuo at chenshuo dot com)#ifndef MUDUO_BASE_MUTEX_H #define MUDUO_BASE_MUTEX_H#include "muduo/base/CurrentThread.h" #include "muduo/base/noncopyable.h" #include <assert.h> #include <pthread.h>// Thread safety annotations { // https://clang.llvm.org/docs/ThreadSafetyAnalysis.html// Enable thread safety attributes only with clang. // The attributes can be safely erased when compiling with other compilers. #if defined(__clang__) && (!defined(SWIG)) #define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) #else #define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op #endif#define CAPABILITY(x) \THREAD_ANNOTATION_ATTRIBUTE__(capability(x))#define SCOPED_CAPABILITY \THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)#define GUARDED_BY(x) \THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))#define PT_GUARDED_BY(x) \THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))#define ACQUIRED_BEFORE(...) \THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))#define ACQUIRED_AFTER(...) \THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))#define REQUIRES(...) \THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__))#define REQUIRES_SHARED(...) \THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__))#define ACQUIRE(...) \THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__))#define ACQUIRE_SHARED(...) \THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__))#define RELEASE(...) \THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__))#define RELEASE_SHARED(...) \THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__))#define TRY_ACQUIRE(...) \THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__))#define TRY_ACQUIRE_SHARED(...) \THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__))#define EXCLUDES(...) \THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))#define ASSERT_CAPABILITY(x) \THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))#define ASSERT_SHARED_CAPABILITY(x) \THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x))#define RETURN_CAPABILITY(x) \THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))#define NO_THREAD_SAFETY_ANALYSIS \THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)// End of thread safety annotations }#ifdef CHECK_PTHREAD_RETURN_VALUE#ifdef NDEBUG __BEGIN_DECLS extern void __assert_perror_fail (int errnum,const char *file,unsigned int line,const char *function)noexcept __attribute__ ((__noreturn__)); __END_DECLS #endif#define MCHECK(ret) ({ __typeof__ (ret) errnum = (ret); \if (__builtin_expect(errnum != 0, 0)) \__assert_perror_fail (errnum, __FILE__, __LINE__, __func__);})#else // CHECK_PTHREAD_RETURN_VALUE#define MCHECK(ret) ({ __typeof__ (ret) errnum = (ret); \assert(errnum == 0); (void) errnum;})#endif // CHECK_PTHREAD_RETURN_VALUEnamespace muduo {// Use as data member of a class, eg. // // class Foo // { // public: // int size() const; // // private: // mutable MutexLock mutex_; // std::vector<int> data_ GUARDED_BY(mutex_); // }; class CAPABILITY("mutex") MutexLock : noncopyable {public:MutexLock(): holder_(0){MCHECK(pthread_mutex_init(&mutex_, NULL));}~MutexLock(){assert(holder_ == 0);MCHECK(pthread_mutex_destroy(&mutex_));}// must be called when locked, i.e. for assertionbool isLockedByThisThread() const{return holder_ == CurrentThread::tid();}void assertLocked() const ASSERT_CAPABILITY(this){assert(isLockedByThisThread());}// internal usagevoid lock() ACQUIRE(){MCHECK(pthread_mutex_lock(&mutex_));assignHolder();}void unlock() RELEASE(){unassignHolder();MCHECK(pthread_mutex_unlock(&mutex_));}pthread_mutex_t* getPthreadMutex() /* non-const */{return &mutex_;}private:friend class Condition;class UnassignGuard : noncopyable{public:explicit UnassignGuard(MutexLock& owner): owner_(owner){owner_.unassignHolder();}~UnassignGuard(){owner_.assignHolder();}private:MutexLock& owner_;};void unassignHolder(){holder_ = 0;}void assignHolder(){holder_ = CurrentThread::tid();}pthread_mutex_t mutex_;pid_t holder_; };// Use as a stack variable, eg. // int Foo::size() const // { // MutexLockGuard lock(mutex_); // return data_.size(); // } class SCOPED_CAPABILITY MutexLockGuard : noncopyable {public:explicit MutexLockGuard(MutexLock& mutex) ACQUIRE(mutex): mutex_(mutex){mutex_.lock();}~MutexLockGuard() RELEASE(){mutex_.unlock();}private:MutexLock& mutex_; };} // namespace muduo// Prevent misuse like: // MutexLockGuard(mutex_); // A tempory object doesn't hold the lock for long! #define MutexLockGuard(x) error "Missing guard object name"#endif // MUDUO_BASE_MUTEX_HCondition.h
// Use of this source code is governed by a BSD-style license // that can be found in the License file. // // Author: Shuo Chen (chenshuo at chenshuo dot com)#ifndef MUDUO_BASE_CONDITION_H #define MUDUO_BASE_CONDITION_H#include "muduo/base/Mutex.h"#include <pthread.h>namespace muduo {//封裝了條件變量的操作 class Condition : noncopyable {public:explicit Condition(MutexLock& mutex): mutex_(mutex){MCHECK(pthread_cond_init(&pcond_, NULL)); //初始化}~Condition(){MCHECK(pthread_cond_destroy(&pcond_)); //銷毀}void wait(){MutexLock::UnassignGuard ug(mutex_);MCHECK(pthread_cond_wait(&pcond_, mutex_.getPthreadMutex()));}// returns true if time out, false otherwise.bool waitForSeconds(double seconds);void notify(){MCHECK(pthread_cond_signal(&pcond_)); //一對一}void notifyAll(){MCHECK(pthread_cond_broadcast(&pcond_)); //廣播}private:MutexLock& mutex_;pthread_cond_t pcond_; };} // namespace muduo#endif // MUDUO_BASE_CONDITION_HCondition.cc
// Use of this source code is governed by a BSD-style license // that can be found in the License file. // // Author: Shuo Chen (chenshuo at chenshuo dot com)#include "muduo/base/Condition.h"#include <errno.h>// returns true if time out, false otherwise. bool muduo::Condition::waitForSeconds(double seconds) {struct timespec abstime;// FIXME: use CLOCK_MONOTONIC or CLOCK_MONOTONIC_RAW to prevent time rewind.clock_gettime(CLOCK_REALTIME, &abstime);const int64_t kNanoSecondsPerSecond = 1000000000;int64_t nanoseconds = static_cast<int64_t>(seconds * kNanoSecondsPerSecond);abstime.tv_sec += static_cast<time_t>((abstime.tv_nsec + nanoseconds) / kNanoSecondsPerSecond);abstime.tv_nsec = static_cast<long>((abstime.tv_nsec + nanoseconds) % kNanoSecondsPerSecond);MutexLock::UnassignGuard ug(mutex_);return ETIMEDOUT == pthread_cond_timedwait(&pcond_, mutex_.getPthreadMutex(), &abstime); }?
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的muduo之mutex和condition的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: muduo之GzipFile
- 下一篇: muduo之ThreadLocal