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_H
Condition.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_H
Condition.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);
}
muduo之mutex和condition相关推荐
- muduo之CountDownLatch.cc
CountDownLatch用线程同步的. CountDownLatch.h // Use of this source code is governed by a BSD-style license ...
- muduo之ThreadPool
muduo中的线程池. ThreadPool.h // Use of this source code is governed by a BSD-style license // that can b ...
- muduo之BlockingQueue
BlockingQueue是muduo是无界队列,利用队列(deque)实现,向队列中加入和取出元素用互斥量和条件变量结合的方式来操作,就是一个线程同步的问题. BlockingQueue.h // ...
- muduo之EventLoopThread
muduo用EventLoopThread提供了对应eventloop和thread的封装,意为I/O线程类,EventLoopThread可以创建一个IO线程,通过startLoop返回一个IO线程 ...
- muduo学习笔记 线程类
learn_muduo 线程属性 线程标识 pthreadId_,pid_t 线程函数 func_ 线程名字 name_ 线程序号 numCreated_ bool started_; // 线程状态 ...
- muduo学习笔记 - 第2章 线程同步精要
第2章 线程同步精要 2.1 互斥器 (mutex) 互斥器保护了临界区,任何时刻最多只能有一个线程在mutex划出的临界区内活动 推荐使用原则: 用RAII手法封装mutex的创建.销毁.加锁.解锁 ...
- muduo之ThreadLocal
ThreadLocal用来存储线程私有数据的类. // Use of this source code is governed by a BSD-style license // that can b ...
- muduo之LogFile
muduo之LogFile,LogFile是控制日志怎么和文件打交道,其中包含常用的对日志处理的一些操作.AsyncLogging异步日志需要调用LogFile的接口将日志写入文件,其中包含了Appe ...
- muduo之TcpClient
muduo用TcpClient发起连接,TcpClient有一个Connector连接器,TCPClient使用Conneccor发起连接, 连接建立成功后, 用socket创建TcpConnecti ...
最新文章
- ASP.Net中利用CSS实现多界面两法
- 单轴步进驱动模块SH-20403
- PostgreSQL学习手册(四) 常用数据类型
- 【LeetCode从零单排】No38.CountAndSay
- C++Primer Plus (第六版)阅读笔记 + 源码分析【第四章:复合类型】
- (转)怎么实时查看mysql当前连接数
- LINUX系统中动态链接库的创建与使用
- A Filter of Java URL Encoding: GetQueryStringEn...
- spring,mybatis事务管理配置与@Transactional注解使用[转]
- perl 的 localtime、timelocal、strftime关于时间的函数
- 数据需求有多野?“三连问”帮你处理得明明白白
- 什么是国家机关、国有企业、事业单位?
- Primeng修改组件样式
- 阿里天池大数据之移动推荐算法大赛总结及代码全公布
- 机器学习基础 EM算法
- rpx单位的换算的过程
- 电脑技巧:Win7、Win10、Win11如何选择,看完你就懂了
- Python开发【第六章】:面向对象
- es6根据对象属性获取到当前值的下标
- 【生信】初探基因定位和全基因组关联分析