Linux 线程 1.2 — 线程同步之互斥量加锁解锁 (4)
互斥量及其相关 API互斥量(mutex)从本质上来说是一把锁,在访问共享资源前对互斥量进行加锁,在访问完成后释放互斥量上的锁。对互斥量进行加锁后,任何其他试图再次对互斥量加锁的线程将会被阻塞直到当前线程释放该互斥锁。如果释放互斥锁时有多个线程阻塞,所有在该互斥锁上的阻塞线程都会变成可运行状态,第一个变为可运行状态的线程可以对互斥量加锁,其他线程将会看到互斥锁依然被锁住,只能回去等待它重新变为可用
互斥量及其相关 API
互斥量(mutex)从本质上来说是一把锁,在访问共享资源前对互斥量进行加锁,在访问完成后释放互斥量上的锁。对互斥量进行加锁后,任何其他试图再次对互斥量加锁的线程将会被阻塞直到当前线程释放该互斥锁。如果释放互斥锁时有多个线程阻塞,所有在该互斥锁上的阻塞线程都会变成可运行状态,第一个变为可运行状态的线程可以对互斥量加锁,其他线程将会看到互斥锁依然被锁住,只能回去等待它重新变为可用。在这种方式下,每次只有一个线程可以向前运行。
1. 创建和销毁锁
锁可以被静态或动态创建,可以用宏 PTHREAD_MUTEX_INITIALIZER 来静态的初始化锁,采用这种方式比较容易理解,互斥锁是 pthread_mutex_t 的结构体,而这个 宏 是一个结构常量,如下可以完成静态的初始化锁:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
另外锁可以用pthread_mutex_init函数动态的创建
关于锁的属性
锁的动态创建
#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *restrict_mutex,const pthread_mutexattr_t *restrict_attr);
该函数用于C函数的多线程编程中,互斥锁的初始化。
以动态方式创建互斥锁的,参数attr指定了新建互斥锁的属性。如果参数attr为空,则使用默认的互斥锁属性,默认属性为快速互斥锁 。
互斥锁的属性在创建锁的时候指定,在LinuxThreads实现中仅有一个锁类型属性,不同的锁类型在试图对一个已经被锁定的互斥锁加锁时表现不同。
函数成功执行后,互斥锁被初始化为未锁住态。
int pthread_mutex_destory(pthread_mutex_t mutex);
返回值 : 若成功则返回 0 ,失败则返回 错误编号
int pthread_mutex_init是一条指令,是中断指令的标识。
对于初始化互斥量,只需把 attr 设置为 NULL;
2. 加锁与解锁
#include <pthread.h>
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,否则返回错误编号。
如果线程不希望被阻塞,它可以使用pthread_mutex_trylock尝试对互斥量进行加锁。如果调用pthread_mutex_trylock时互斥量处于未锁住状态,那么
pthread_mutex_trylock将锁住互斥量,不会出现阻塞并返回0,否则
pthread_mutex_trylock就会失败,不能锁住互斥量,而返回EBUSY。
互斥量,本质上是一把锁,这是 UNIX环境高级编程中文版的定义,但是,我认为此定义不好,互斥量,应该是被所起来的东西,就是处于 加锁,解锁之间的 代码。
什么是死锁?
死锁就是两个线程,两把锁,每一个线程都拿到了一把锁,而互斥量中,都去拿另一把锁,这就是死锁,谁也拿不到对方的锁,锁死了这两个线程。
eg :
pthread_mutex_t mutex;
pthread_mutex_t mutex2; // 先定义两个结构体,(锁)
void * funcl1(void * arg){
pthread_mutex_lock(&mutex);
sleep(1);
pthread_mutex_lock(&mutex2);
i++;
pthread_mutex_unlock(&mutex);
pthread_mutex_unlock(&mutex2);
}
void * funcl2(void * arg){
pthread_mutex_lock(&mutex2);
sleep(1);
pthread_mutex_lock(&mutex);
i++;
pthread_mutex_unlock(&mutex);
pthread_mutex_unlock(&mutex2);
}
两个线程,先后调用了两个锁,相互锁死。
更多推荐
所有评论(0)