6.互斥量

来源:互联网 发布:尼尔森数据查询 编辑:程序博客网 时间:2024/04/30 10:10

互斥量是一种特殊的变量,它可以处于锁定状态(locked),也可以处于解锁状态(unlocked)。如果互斥量是锁定的,那么必然有一个线程持有或拥有这个互斥量。如果没有任何一个线程持有这个互斥量,那么这个互斥量就处于解锁、空闲或可用状态(这三种状态有区别?!)。当互斥量空闲,并且有一个线程试图获取这个互斥量时,这个线程就可以获得这个互斥量而不会被阻塞。如果互斥量处于锁定状态,那么试图获取这个互斥量的线程将被阻塞,并加入到这个互斥量的等待队列中。等待队列中的线程获得互斥量的顺序由系统决定。这样的机制解决了共享资源的互斥(Mutual Exclusive)访问问题。

创建并初始化一个互斥量

POSIX使用pthread_mutex_t类型的变量来表示互斥量。程序在使用pthread_mutex_t变量之前,必须对其进行初始化。

对于静态分配的pthread_mutex_t变量,只要将PTHREAD_MUTEX_INITIALIZER赋给这个变量即可,如:

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

对于动态创建或不使用默认属性的互斥量来说,就要调用pthread_mutex_init函数来对其进行初始化,此函数的形式如下:

int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);

静态初始化通常比pthread_mutex_init更有效,而且可以在定义为全局变量时即完成初始化,这样可以保证在任何线程开始执行之前,初始化即已完成。

销毁一个互斥量

当不再使用应经定义了的互斥量时,需要将互斥量销毁。函数pthread_mutex_destroy用于销毁互斥量。它的形式为:

int pthread_mutex_destory(pthread_mutex_t *mutex);

参数mutex指向要销毁的互斥量。如果成功,函数返回0...

可以用pthread_mutex_init()重新初始化被销毁的互斥量。

对互斥量的锁定和解锁

POSIX中有两个可以用来获取互斥量的函数,pthread_mutex_lock()和pthread_mutex_trylock()。pthread_mutex_lock()函数会使调用这个函数的线程移植阻塞到互斥量可用为止,而pthread_mutex_trylock()会立即返回,如果互斥量空闲,那么调用这个函数的线程将获得互斥量,否则返回EBUSY。pthread_mutex_unlock()用来释放互斥量。

这三个函数的形式如下:

int pthread_mutex_lock(pthread_mutex_t *mutex);

int pthread_mutex_trylock(pthread_mutex_t *mutex);

int pthread_mutex_unlock(pthread_mutex_t *mutex);

若成功,都是返回0。

互斥量应用实例

由于在大多数机器中,对变量的增量和减量操作都不是原子的。比如通常情况下,增量操作包括三个步骤:将内存中数值装载到CPU寄存器中,将寄存器的值加1,将寄存器中的值写回内存。而机器并不能保证这三步之间不会发生调度,这就导致对变量的增量操作和减量操作有可能得不到期望的结果...

int increase(int *integer){static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;int error;if (error = pthread_mutex_lock(&lock);return error;*integer++;return pthread_mutex_unlock(&lock);}int decrease(int *integer){static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;int error;if (error = pthread_mutex_lock(&lock);return error;*integer--;return pthread_mutex_unlock(&lock);}
对于互斥量,我有一些体会:

体会1:互斥量只是一种手段。如何理解呢?它是用来保护某个共享资源的,对互斥量的使用重在“自觉”,比如有三个线程one、two、three,二者都需要处理一个全局变量share,共享一个互斥变量mutex,程序员需要做的是,不管在哪里?不管对于哪个线程,在写变量share时,都要获取(调用pthread_mutex_lock函数)互斥量mutex,然后才开始写,写完之后再释放(pthread_mutex_unlock函数)mutex,如此这般,才能保证share只被一个人写;但若有些线程“不听话”,比如线程three,它不这样做,不进行神马pthread_mutex_lock()、pthread_mutex_unlock()操作,它也能操作share,但是这样就违背了程序设计的初衷。互斥量只是一种手段,使用全屏自觉。

体会2:体会1中讲到的是对share的“写操作”进行锁定,但这不是绝对的,很多时候要是具体情况而定,有时要求“读”“写”都锁定,有时只要求“写”锁定...


原创粉丝点击