Linux组件封装之一:MUtexLock

本文对pthread_mutex_t 进行简易的封装;

互斥锁主要用于互斥,描述的是一种竞争关系,主要是一个 一种资源或者代码, 在一段时间内 至多能被一个程序访问。

而条件变量主要用于线程间同步, 描述的是一种协作关系

Linux中互斥锁的应用比较简单,通用的有以下几个函数:

1 int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
2 int pthread_mutex_lock(pthread_mutex_t *mutex);
3 int pthread_mutex_unlock(pthread_mutex_t *mutex);
4 int pthread_mutex_destroy(pthread_mutex_t *mutex);

说明:

1、MutexLock、以及下篇文章中的Condition利用构造函数和析构函数自动完成资源的申请和释放;

2、MutexLock、Condition和Thread 都涉及到系统资源,这些类 全部为不可复制的;例如,a程序启动了一把锁,而另外一个程序 b 复制了这把锁,若某一时刻,a程序把这把锁销毁了,这时无论如何,b程序都不可能拥有锁这个系统资源。因此,我们将其作为 NonCopyable 类 的私有继承。

一、NonCopyable类:

 1 #ifndef NONCOPYABLE_H_
 2 #define NPNCOPYABLE_H_
 3
 4 class NonCopyable //禁用值语义
 5 {
 6     public:
 7         NonCopyable(){ }
 8         ~NonCopyable(){ }
 9
10     private:
11         NonCopyable(const NonCopyable &);//no copy
12         void operator=(const NonCopyable &);//no assignment
13 };
14
15 #endif

二、互斥锁类(MutexLock),代码如下:

 1 #ifndef MUTEX_LOCK_H
 2 #define MUTEX_LOCK_H
 3 #include "NonCopyable.h"
 4 #include "pthread.h"
 5 #include <assert.h>
 6
 7 //attention
 8 class MutexLock:NonCopyable
 9 {
10     public:
11         MutexLock();
12         ~MutexLock();
13
14         void lock(); //上锁
15         void unlock();//释放锁
16         bool isLocking() const { return isLocked_;}//判断锁的状态
17         pthread_mutex_t getMutex()
18         { return mutex_; }
19     private:
20         pthread_mutex_t mutex_;
21         bool isLocked_;//标记是否上锁
22 };
23
24 MutexLock::MutexLock()
25     :isLocked_(false)
26 {
27     pthread_mutex_init(&mutex_, NULL);
28 }
29 MutexLock::~MutexLock()
30 {
31     //判断是否已经解锁
32     assert(!isLocking());
33     pthread_mutex_destroy(&mutex_);
34 }
35 void MutexLock::lock()
36 {
37     isLocked_ = true;
38     pthread_mutex_lock(&mutex_);
39 }
40 void MutexLock::unlock()
41 {
42     isLocked_ = false;
43     pthread_mutex_unlock(&mutex_);
44 }
45
46 #endif
时间: 2024-10-29 19:06:22

Linux组件封装之一:MUtexLock的相关文章

Linux组件封装之五:生产者消费者问题

生产者,消费者问题是有关互斥锁(MutexLock).条件变量(Condition).线程(Thread)的经典案例: 描述的问题可以叙述为 生产者往buffer中投放产品,而消费者则从buffer中消费产品. 生产着消费者问题的难点在于: 为了缓冲区数据的安全性,一次只允许一个线程进入缓冲区投放或者消费产品,这个buffer就是所谓的临界资源. 生产者往缓冲区中投放产品时,如果缓冲区已满,那么该线程需要等待,即进入阻塞状态,一直到消费者取走产品为止. 相应的,消费者欲取走产品,如果此时缓冲区为

Linux组件封装(五)一个生产者消费者问题示例

生产者消费者问题是计算机中一类重要的模型,主要描述的是:生产者往缓冲区中放入产品.消费者取走产品.生产者和消费者指的可以是线程也可以是进程. 生产者消费者问题的难点在于: 为了缓冲区数据的安全性,一次只允许一个线程进入缓冲区,它就是所谓的临界资源. 生产者往缓冲区放物品时,如果缓冲区已满,那么需要等待,一直到消费者取走产品为止. 消费者取走产品时,如果没有物品,需要等待,一直到有生产者放入为止. 第一个问题属于互斥问题,我们需要使用一把互斥锁,来实现对缓冲区的安全访问. 后两个属于同步问题,两类

Linux组件封装(七)——线程池的简单封装

线程池的封装,基础思想与生产者消费者的封装一样,只不过我们是将线程池封装为自动获取任务.执行任务,让用户调用相应的接口来添加任务. 在线程池的封装中,我们同样需要用到的是MutexLock.Condition.Thread这些基本的封装. 基础封装如下: MutexLock: 1 #ifndef MUTEXLOCK_H 2 #define MUTEXLOCK_H 3 4 #include "NonCopyable.h" 5 #include <pthread.h> 6 #i

Linux组件封装(一)中互斥锁MutexLock的封装

本文对Linux中的pthread_mutex_t做一个简易的封装. 互斥锁主要用于互斥,互斥是一种竞争关系,主要是某一个系统资源或一段代码,一次做多被一个线程访问. 条件变量主要用于同步,用于协调线程之间的关系,是一种合作关系. Linux中互斥锁的用法很简单,最常用的是以下的几个函数: int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr); int pthread_mutex_

Linux组件封装(四)使用RAII技术实现MutexLock自动化解锁

我们不止一次写过这种代码: { mutex_.lock(); //XXX if(....) return; //XXX mutex_.unlock(); } 显然,这段代码中我们忘记了解锁.那么如何防止这种情况,我们采用和智能指针相同的策略,把加锁和解锁的过程封装在一个对象中. 实现"对象生命期"等于"加锁周期". 代码如下: class MutexLockGuard : NonCopyable { public: MutexLockGuard(MutexLock

Linux组件封装(一) 互斥锁MutexLock

由于pthread系列的函数都是成功时返回0,我们需要一段判断处理错误的代码: #define TINY_CHECK(exp) if(!exp) { fprintf(stderr, "File : %s, Line : %d Exp : ["#exp"] is true, abort.\n", __FILE__, __LINE__); abort(); } MutexLock的封装如下: 1 #ifndef MUTEXLOCK_H 2 #define MUTEXLO

Linux组件封装之二:Condition

本博文讨论Linux中的条件变量Condition的封装: 条件变量Condition 主要描述的是 线程间 的同步,即协作关系. Linux中的条件变量通常涉及以下几个函数: int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr); int pthread_cond_signal(pthread_cond_t *cond); int pthread_cond_broadcast(pthread_con

Linux组件封装(六)——定时器的简单封装

在Linux中,有一种简单的定时器——timerfd,它通过查看fd是否可读来判断定时器时候到时. timerfd中常用的函数有timerfd_create.timerfd_settime.timerfd_gettime,这些函数都相对简单,我们可以到man手册来查看用法. 值得注意的是:create中的参数CLOCK_REALTIME是一个相对时间,我们可以通过调整系统时间对其进行调整,而CLOCK_MONOTIC是一个绝对时间,系统时间的改变不会影响它.在create中,flags一般设置为

Linux组件封装(八)——Socket的封装

我们要封装Socket,首先我们需要了解Socket需要哪些要素: 1) 首先,一个套接字创建后,需要绑定一块网卡的IP,以及连接的对口号,所以我们先封装InetAddr. 在class中,仅有的一个私有成员就是struct sockaddr_in类型的一个对象,我们需要将该对象的几种赋值与创建封装到类中,这样,我们仅需传递相应的IP与port即可获得一个addr. 在这里,我们为了方便获得该addr的IP及port,封装几个将addr转化为IP及port的函数,这样我们仅需调用函数即可. 然后