[Muduo网络库源码分析] (6) base/Mutex.h_互斥锁操作
2017-07-31 09:18
316 查看
互斥锁操作
功能:封装对互斥锁的操作
知识点:
MCHECK()宏的实现#define MCHECK(ret) ({ __typeof__ (ret) errnum = (ret); \ if (__builtin_expect(errnum != 0, 0)) \ __assert_perror_fail (errnum, __FILE__, __LINE__, __func__);})
线程与锁的对应关系
用途:
可用于多线程互斥锁的操作
亮点程序:
//对锁进行解锁,加锁操作 class MutexLockGuard : boost::noncopyable { public: explicit MutexLockGuard(MutexLock& mutex) : mutex_(mutex) { mutex_.lock(); } ~MutexLockGuard() { mutex_.unlock(); } private: MutexLock& mutex_; };
上述代码在使用过程中非常方便,其可以对作用域内的内容上锁,并实现自动解锁
{ MutexLockGuard mu = MutexLockGuard(mutex_) ... }
代码及分析:
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 <boost/noncopyable.hpp>
#include <assert.h>
#include <pthread.h>
#ifdef CHECK_PTHREAD_RETURN_VALUE
#ifdef NDEBUG
//用C++编译器统一处理
__BEGIN_DECLS
extern void __assert_perror_fail (int errnum,
const char *file,
unsigned int line,
const char *function)
//无返回值
__THROW __attribute__ ((__noreturn__));
__END_DECLS
#endif
//检查是否出错 ,__typeof__定义与ret类型相同的errnum,大多数情况下不执行if语句
#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_VALUE
namespace 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 MutexLock : boost::noncopyable
{
public:
//构造函数,初始化线程ID,初始化锁
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 assertion
bool isLockedByThisThread() const
{
return holder_ == CurrentThread::tid();
}
//如果不是作用于当前线程,则退出
void assertLocked() const
{
assert(isLockedByThisThread());
}
// internal usage
//上锁,并存储上锁的线程ID
void lock()
{
MCHECK(pthread_mutex_lock(&mutex_));
assignHolder();
}
//解锁,并置当前线程ID标记为0
void unlock()
{
unassignHolder();
MCHECK(pthread_mutex_unlock(&mutex_));
}
//返回锁地址
pthread_mutex_t* getPthreadMutex() /* non-const */
{
return &mutex_;
}
private:
friend class Condition;
//对加锁的线程进行线程ID的改变
class UnassignGuard : boost::noncopyable
{
public:
UnassignGuard(MutexLock& owner)
: owner_(owner)
{
owner_.unassignHolder();
}
~UnassignGuard()
{
owner_.assignHolder();
}
private:
MutexLock& owner_;
};
//对holder_置零
void unassignHolder()
{
holder_ = 0;
}
//给holder_赋值为当前线程ID
void assignHolder()
{
holder_ = CurrentThread::tid();
}
pthread_mutex_t mutex_;//互斥锁
pid_t holder_;//线程ID
};
// Use as a stack variable, eg.
// int Foo::size() const
// {
// MutexLockGuard lock(mutex_);
// return data_.size();
// }
//对锁进行解锁,加锁操作 class MutexLockGuard : boost::noncopyable { public: explicit MutexLockGuard(MutexLock& mutex) : mutex_(mutex) { mutex_.lock(); } ~MutexLockGuard() { mutex_.unlock(); } private: MutexLock& mutex_; };
}
// 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
相关文章推荐
- [Muduo网络库源码分析] (8) base/StringPiece.h_字符串参数传递类型
- [Muduo网络库源码分析] (9) base/Thread.cc_h_CurrentThread_h线程对象
- [Muduo网络库源码分析] (10) base/ThreadPoll_cc_h_线程池
- [Muduo网络库源码分析] (11) base/Types.h_基本类型声明
- [Muduo网络库源码分析] (1) base/Atomic.h_原子操作与原子整数
- [Muduo网络库源码分析] (2) base/Condition.cc_h_条件变量操作
- [Muduo网络库源码分析] (3) base/CountDownLatch.cc_h_“倒计时门闩”同步
- [Muduo网络库源码分析] (4) base/Exception_cc_h_带 stack trace 的异常基类
- [Muduo网络库源码分析] (5) base/FileUtil.cc_h_文件操作
- [Muduo网络库源码分析] (7) base/Singleton.h_SINGLETON对象创建型模式
- cartographer源码分析(9)-common-mutex.h
- OSMDroid源码分析之瓦片载入基类:MapTileModuleProviderBase
- 【FastDev4Android框架开发】BaseAdapterHelper详解源码分析,让你摆脱狂写一堆Adapter烦恼(二十五)
- Python标准库源码分析:BaseHTTPServer.py
- BaseHTTPServer与CGIHTTPServer源码分析 - 技术手札
- ⑥NuPlayer播放源码分析之DecoderBase分析 NuPlayer播放源码分析之DecoderBase分析
- Wangle源码分析:EventBaseHandler、AsyncSocketHandler
- Muduo网络库源码分析(一) EventLoop事件循环(Poller和Channel)
- Yii2.0源码分析之——YiiBase自动加载类、引用文件(autoload)
- MVVMLight源码分析之消息机制和ViewModelBase