本文对Linux中的pthread_mutex_t做一个简易的封装。

互斥锁主要用于互斥,互斥是一种竞争关系,主要是某一个系统资源或一段代码,一次做多被一个线程访问。

条件变量主要用于同步,用于协调线程之间的关系,是一种合作关系

Linux中互斥锁的用法很简单,最常用的是以下的几个函数:

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_destroy(pthread_mutex_t *mutex);

我们利用RAII技术,将mutex的初始化和销毁放在构造函数和析构函数中

这里注意,pthread系列的函数都是成功时返回0,我采用一个轻量级的检查手段,来判断处理错误。

//用于pthread系列函数的返回值检查
#define TINY_CHECK(exp) \
if(!(exp)) \
{ \
fprintf(stderr, "File:%s, Line:%d Exp:[" #exp "] is true, abort.\n", __FILE__, __LINE__); abort();\
}

代码如下:

#ifndef MUTEXLOCK_H
#define MUTEXLOCK_H #include "NonCopyable.h"
//#include <boost/noncopyable.hpp>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h> //用于pthread系列函数的返回值检查
#define TINY_CHECK(exp) \
if(!(exp)) \
{ \
fprintf(stderr, "File:%s, Line:%d Exp:[" #exp "] is true, abort.\n", __FILE__, __LINE__); abort();\
} class MutexLock : NonCopyable
{
friend class Condition;
public:
MutexLock();
~MutexLock();
void lock();
void unlock(); bool isLocking() const { return isLocking_; }
pthread_mutex_t *getMutexPtr() //思考为什么不是const
{ return &mutex_; } private:
void restoreMutexStatus() //提供给Condition的wait使用
{ isLocking_ = true; } pthread_mutex_t mutex_;
bool isLocking_; //是否上锁
}; class MutexLockGuard : NonCopyable
{
public:
MutexLockGuard(MutexLock &mutex) :mutex_(mutex)
{ mutex_.lock(); }
~MutexLockGuard()
{ mutex_.unlock(); }
private:
MutexLock &mutex_;
}; #endif //MUTEXLOCK_H

cpp文件:

#include "MutexLock.h"
#include <assert.h> MutexLock::MutexLock()
:isLocking_(false)
{
TINY_CHECK(!pthread_mutex_init(&mutex_, NULL));
} MutexLock::~MutexLock()
{
assert(!isLocking());//确保解锁
TINY_CHECK(!pthread_mutex_destroy(&mutex_));
} void MutexLock::lock()
{ TINY_CHECK(!pthread_mutex_lock(&mutex_));
isLocking_ = true;
} void MutexLock::unlock()
{
isLocking_ = false;
TINY_CHECK(!pthread_mutex_unlock(&mutex_));
}

后面我们可以继续使用RAII,将lock和unlock封装在同一个类中。

Linux组件封装(一)中互斥锁MutexLock的封装的更多相关文章

  1. 深入理解Solaris内核中互斥锁(mutex)与条件变量(condvar)之协同工作原理

    在Solaris上写内核模块总是会用到互斥锁(mutex)与条件变量(condvar), 光阴荏苒日月如梭弹指一挥间,Solaris的大船说沉就要沉了,此刻心情不是太好(Orz).每次被年轻的有才华的 ...

  2. 【Linux C 多线程编程】互斥锁与条件变量

    一.互斥锁 互斥量从本质上说就是一把锁, 提供对共享资源的保护访问. 1) 初始化: 在Linux下, 线程的互斥量数据类型是pthread_mutex_t. 在使用前, 要对它进行初始化: 对于静态 ...

  3. Python进阶(3)_进程与线程中的lock(线程中互斥锁、递归锁、信号量、Event对象、队列queue)

    1.同步锁 (Lock) 当全局资源(counter)被抢占的情况,问题产生的原因就是没有控制多个线程对同一资源的访问,对数据造成破坏,使得线程运行的结果不可预期.这种现象称为“线程不安全”.在开发过 ...

  4. python网络编程中互斥锁与进程之间的通信

    一.互斥锁 进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理. 注意:加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行 ...

  5. Linux多线程的使用一:互斥锁

    多线程经常会在Linux的开发中用到,我想把平时的使用和思考记录下来,一是给自己做个备忘,二是分享给可能会用到的人. POSIX标准下互斥锁是pthread_mutex_t,与之相关的函数有: 1 i ...

  6. Linux互斥锁、条件变量和信号量

    Linux互斥锁.条件变量和信号量  来自http://kongweile.iteye.com/blog/1155490 http://www.cnblogs.com/qingxia/archive/ ...

  7. 深入理解 iOS 开发中的锁

    来源:伯乐在线 - 夏天然后 链接:http://ios.jobbole.com/89474/ 点击 → 申请加入伯乐在线专栏作者 摘要 本文的目的不是介绍 iOS 中各种锁如何使用,一方面笔者没有大 ...

  8. ReactiveSwift源码解析(十一) Atomic的代码实现以及其中的Defer延迟、Posix互斥锁、递归锁

    本篇博客我们来聊一下ReactiveSwift中的原子性操作,在此内容上我们简单的聊一下Posix互斥锁以及递归锁的概念以及使用场景.然后再聊一下Atomic的代码实现.Atomic主要负责多线程下的 ...

  9. 基于Zookeeper实现的分布式互斥锁 - InterProcessMutex

    Curator是ZooKeeper的一个客户端框架,其中封装了分布式互斥锁的实现,最为常用的是InterProcessMutex,本文将对其进行代码剖析 简介 InterProcessMutex基于Z ...

随机推荐

  1. 云服务器基本环境配置(php5.6+mysql+nginx)

    1.安装nginx sudo apt-get install nginx nginx 基本配置 server{ listen ; server_name www.xxxxxx.cn; root /va ...

  2. Java笔记(一)

    1. ConcurrentModificationException 在遍历容器的同时修改容器里的成员对象可能会抛出该异常 http://www.blogjava.net/EvanLiu/archiv ...

  3. BCB中选择文件对话框TOpenDialog过滤后缀名使用方法

    BCB中使用TOpenDialog选择对话框时,直接OpenDialog->Execute()弹出的对话框是显示所有文件的,如果我们希望过滤指定的文件后缀名就需要在Execute()前做一些初始 ...

  4. Jquery操作属性选择器

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. 配置OpenResty支持SSL(不受信任的证书)

    #关闭防火墙 chkconfig iptables off service iptables stop #关闭SELINUX sed -i 's/SELINUX=enforcing/SELINUX=d ...

  6. TP5使用技巧

    1.fetchSql用于直接返回SQL而不是执行查询,适用于任何的CURD操作方法. 例如:$result = Db::table('think_user')->fetchSql(true)-& ...

  7. 计蒜客 18492.Upside down primes-米勒拉宾判大素数 (German Collegiate Programming Contest 2015 ACM-ICPC Asia Training League 暑假第一阶段第三场 K)

    K. Upside down primes 传送门 这个题就是把大数按字符串输进去,判断一下是不是素数,然后反转180度,先判断反转之后的东西是不是一个数,如果是的话,再把这个数判一下是不是素数,如果 ...

  8. Python与数据结构[1] -> 栈/Stack[0] -> 链表栈与数组栈的 Python 实现

    栈 / Stack 目录 链表栈 数组栈 栈是一种基本的线性数据结构(先入后出FILO),在 C 语言中有链表和数组两种实现方式,下面用 Python 对这两种栈进行实现. 1 链表栈 链表栈是以单链 ...

  9. C++中static、const使用方法简介

    众所周知,在c++中,static和const的使用方法是难点,也是重点,值得我们随时温习,所谓温故而知新是也. 下面我们首先说一说static. 1.static的作用 static变量的作用,主要 ...

  10. 六. 异常处理10.Java的内置异常

    在标准包java.lang中,Java定义了若干个异常类.前面的例子曾用到其中一些.这些异常一般是标准类RuntimeException的子类.因为java.lang实际上被所有的Java程序引入,多 ...