Linux多线程学习(四)互斥量

一、互斥量

因为临界区的代码段必须以互斥的方式执行,即临界区范围内只能有一个活动的执行线程。互斥量就是用来保护这种临界区的特殊变量,又称互斥锁,有两种状态:锁定状态、解锁状态。

如果互斥锁是锁定状态,表示某个线程正持有这个互斥锁;如果互斥锁处于解锁状态,则表示没有线程持有这个互斥锁。

每个互斥锁内部都有一个等待队列,用来保存等待该互斥锁的线程,当某个互斥锁处于锁定状态时,如果某个线程视图获取这个互斥锁,它将被被阻塞并添加到互斥锁内的等待队列中。

二、互斥量的使用:

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;
}

运行结果:

Linux多线程学习(四)互斥量_第1张图片

从运行结果中可以看出:如果不加互斥量两个线程会轮流调用线程的入口函数,倘若这个线程入口函数内的代码段是临界资源,那么就不应该出现上面的这种结果,而应该是某一个线程退出临界区后,另一个线程才能进入。

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;
}

运行结果:

Linux多线程学习(四)互斥量_第2张图片

你可能感兴趣的:(Linux多线程学习(四)互斥量)