首页 > 代码库 > 工具类之Mutex

工具类之Mutex

<style></style>

MutexAndroid4.4的源代码包的./system/core/include/utils/Mutex.h中定义并且实现。

我们先复习一下MutexLinux中功能:

Mutex出生的意义就是在多个线程中同一时间只有一个线程可以访问Mutex要保护的数据。

它的工作原理是某一个线程要访问公共资源的时候先锁定这个mutex,完成操作之后对mutex解锁,在此期间如果有其它的线程也要访问公共资源,它就先要去锁mutex,当它发现mutex已经被锁住了,那么这个线程就是阻塞在那儿。等mutex解锁之后所有阻塞在mutex的线程都会醒来,只有第一个醒来的会抢到mutex,其它没有抢到的发现自己晚了一步,只能继续阻塞在那儿,等待下次机会。

任何东西都不可能是完美的,Mutex也不是,所以它会死锁,一个线程锁定mutex两次,线程就会进入死锁状态,为了避免这个问题,可以用trylock,但是如果你的线程使用的mutex不只有一个,那么问题就复杂了,比如有两个线程,各自锁定一个mutex等待锁定另一个,那么这两个线程都进入了死锁状态,不死不休。

Mutex有以下几个操作:

int pthread_mutex_lock(pthread_mutex_t *mutex);int pthread_mutex_trylock(pthread_mutex_t *mutex);int pthread_mutex_unlock(pthread_mutex_t *mutex);int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex,const struct timespec *restrict tsptr);

pthread_mutex_lock的性格简单粗暴,直接就奔着mutex去了,锁不上俺着等着。

pthread_mutex_trylock比较圆滑,锁不住mutex也不阻塞,返回个错误值交给下面的代码去解决。

pthread_mutex_unlock也比较粗暴,管你有没有锁定mutex,就解锁,就是这么任性。要知道unlock一个未锁定的mutex结果是undefined behavior results,啥意思“后果自负”

pthread_mutex_timedlock比它大哥 pthread_mutex_lock脾气好些,知道转个弯,设置个超时值。

Linuxmutex可用于线程也可用于进程,区别在于private还是shared。同样,android中的Mutex是系统相关的,意思就是Mutex类就是对linuxmutex的包装,所以它也可以用于线程和进程,同样分为privateshared

Mutex我们复习完了,现在看看Android中的做法

Mutex的构造函数有三个,可以无需参数,也可以带一个名子,还可以带个名子的同时带一个类型。它的操作也还是那三个lock,unlock以及trylock,这些也都是和我们之前了解的相同。

为了简化一般的mutex操作,在class Mutex中定义了一个内部类Autolock,它利用{}作用域实现自动解锁,看一下它的构造函数就知道了:

inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); }inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); }

创建对象的同时锁住传入的mutex,再看它的析构函数:

inline ~Autolock() { mLock.unlock(); }

我们知道在{}中创建的变量,变开这个大括号时就要销毁,于是就自动调用析构函数了。这个类容易理解,不过我特别喜欢它这种对规则的利用!

new Mutex(1);构造的是进程间使用的Mutex,它的类型是SHARED。一般是在线程中使用,所以你都看不到它调用构造函数,都是直接拿来用,比如这样:

Mutex::Autolock _l(mLock);

 

为了简化代码:

typedef Mutex::Autolock AutoMutex

 

我们使用Autolock的时候就可以在大括号内直接new一个AutoMutex对象就可以了。

它的用法也很简单,直接在一个大括号内AutoMutex xxx(mLock);或者是Mutex::Autolock xx(mLock);就行了。当然前提是mLock要初始化

 

工具类之Mutex