因为临界区的代码段必须以互斥的方式执行,即临界区范围内只能有一个活动的执行线程。互斥量就是用来保护这种临界区的特殊变量,又称互斥锁,有两种状态:锁定状态、解锁状态。
如果互斥锁是锁定状态,表示某个线程正持有这个互斥锁;如果互斥锁处于解锁状态,则表示没有线程持有这个互斥锁。
每个互斥锁内部都有一个等待队列,用来保存等待该互斥锁的线程,当某个互斥锁处于锁定状态时,如果某个线程视图获取这个互斥锁,它将被被阻塞并添加到互斥锁内的等待队列中。
1、创建互斥量 : pthread_mutex_t mutex;
2、互斥量初始化
在使用互斥量之前必须对互斥量进行初始化,互斥量的初始化有两种方式,静态初始化和动态初始化:
(1)静态初始化
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER
(2)动态初始化
动态初始化使用函数:int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);初始化成功返回0,否则返回一个非0的错误码。参数mutex为互斥量指针,attr为互斥量的属性,当attr赋值为NULL时,表示以默认属性初始化互斥量mutex,否则需要先创建互斥量属性,给这个互斥量赋值后在使用。
3、互斥量的销毁
函数:int pthread_mutex_destroy(pthread_mutex_t *mutex);
4、加锁
int pthread_mutex_lock(pthread_mutex_t *mutex);该函数会一直阻塞直到互斥量可用位置;
int pthread_mutex_trylock(pthread_mutex_t *mutex);若某个互斥量处于锁定状态,调用该函数后,立即返回。
5、解锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);
创建两个线程,调用同一个线程入口函数,该函数内循环打印字符串10次。
1.不加互斥锁
#include
#include
#include
#include
#include
//互斥量实验
pthread_t thread1,thread2;
void *pthread_func(void * pra)
{
int i = 0;
int para = (int)pra;
while( (i++) < 10 )
{
printf("%d:called by thread%d\r\n",i,para);
sleep(1);
}
pthread_exit(NULL);
}
int main(void)
{
int res;
int par1 = 1;
int par2 = 2;
res = pthread_create(&thread1,NULL,pthread_func,(void*)par1);
if(res)
{
printf("thread1 create fail\r\n");
exit(-1);
}
res = pthread_create(&thread2,NULL,pthread_func,(void*)par2);
if(res)
{
printf("thread2 create fail\r\n");
exit(-1);
}
pthread_exit(NULL);
return 0;
}
运行结果:
从运行结果中可以看出:如果不加互斥量两个线程会轮流调用线程的入口函数,倘若这个线程入口函数内的代码段是临界资源,那么就不应该出现上面的这种结果,而应该是某一个线程退出临界区后,另一个线程才能进入。
2、加互斥锁
#include
#include
#include
#include
#include
//互斥量实验
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_t thread1,thread2;
void *pthread_func(void * pra)
{
int i = 0;
int para = (int)pra;
//使用互斥量保护临界
pthread_mutex_lock(&lock);
while( (i++) < 10 )
{
printf("%d:called by thread%d\r\n",i,para);
sleep(1);
}
//退出临界区
pthread_mutex_unlock(&lock);
pthread_exit(NULL);
}
int main(void)
{
int res;
int par1 = 1;
int par2 = 2;
res = pthread_create(&thread1,NULL,pthread_func,(void*)par1);
if(res)
{
printf("thread1 create fail\r\n");
exit(-1);
}
res = pthread_create(&thread2,NULL,pthread_func,(void*)par2);
if(res)
{
printf("thread2 create fail\r\n");
exit(-1);
}
//等待线程1,线程2运行结束后,销毁互斥量
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
res = pthread_mutex_destroy(&lock);
if(!res)
{
printf("mutex is destroyed !\r\n");
}
return 0;
}
运行结果: