天天看点

互斥锁的使用以及注意事项以及互斥锁demo

对公共数据进行保护。所有线程【应该】在访问公共数据前先拿锁再访问。但,锁本身不具备强制性。

互斥锁的使用以及注意事项以及互斥锁demo

使用mutex(互斥量、互斥锁)一般步骤:

pthread_mutex_init 函数

初始化一个互斥锁(互斥量) —> 初值可看作1

int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); 
    参 1:传出参数,调用时应传 &mutex 
    	restrict 关键字:只用于限制指针,告诉编译器,所有修改该指针指向内存中内容的操作,只能通过本指针完成。不能通过除本指针以外的其他变量或指针修改 
	参 2:互斥量属性。是一个传入参数,通常传NULL,选用默认属性(线程间共享)。 参APUE.12.4 同步属性 
           
  1. 静态初始化:如果互斥锁 mutex 是静态分配的(定义在全局,或加了 static 关键字修饰),可以直接使用宏进行初始化。e.g. pthead_mutex_t muetx = PTHREAD_MUTEX_INITIALIZER;
  2. 动态初始化:局部变量应采用动态初始化。e.g. pthread_mutex_init(&mutex, NULL)

pthread_mutex_destroy 函数

销毁一个互斥锁

pthread_mutex_lock 函数

加锁。可理解为将mutex–(或 -1),操作后mutex 的值为 0。

pthread_mutex_unlock 函数

解锁。可理解为将mutex ++(或 +1),操作后mutex 的值为 1。

pthread_mutex_trylock 函数

尝试加锁

创建流程:

pthread_mutex_t 类型。 

1. pthread_mutex_t lock;  创建锁

2  pthread_mutex_init; 初始化		

3. pthread_mutex_lock;加锁		

4. 访问共享数据(stdout)		

5. pthrad_mutext_unlock();解锁		

6. pthead_mutex_destroy;销毁锁
           

加锁与解锁

lock 尝试加锁,如果加锁不成功,线程阻塞,阻塞到持有该互斥量的其他线程解锁为止。

unlock 主动解锁函数,同时将阻塞在该锁上的所有线程全部唤醒,至于哪个线程先被唤醒,取决于优先级、调度。默认:先阻塞、先唤醒。

例如:T1 T2 T3 T4 使用一把 mutex 锁。T1 加锁成功,其他线程均阻塞,直至T1 解锁。T1 解锁后,T2 T3 T4 均被唤醒,并自动再次尝试加锁。

注意事项:

​ 尽量保证锁的粒度, 越小越好。(访问共享数据前,加锁。访问结束【立即】解锁。)

​ 互斥锁,本质是结构体。 我们可以看成整数。 初值为 1。(pthread_mutex_init() 函数调用成功。)

​ 加锁: --操作, 阻塞线程。

​ 解锁: ++操作, 换醒阻塞在锁上的线程。

​ try锁:尝试加锁,成功–。失败,返回。同时设置错误号 EBUSY

互斥锁demo

#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<pthread.h>
#include<stdio.h>

pthread_mutex_t mutex;  //定义一把互斥锁

void *tfn(void *arg){
	srand(time(NULL));
	while(1){
		pthread_mutex_lock(&mutex);
		printf("hello ");
		sleep(rand()%3);
		printf("world\n");
		pthread_mutex_unlock(&mutex);
		sleep(rand()%3);
	}
	return NULL;
}

int main(void){
	pthread_t tid;
	srand(time(NULL));
	int ret=pthread_mutex_init(&mutex,NULL);  //初始化互斥锁
	if(ret!=0){
		fprintf(stderr,"mute init error:%s\n",sterror(ret));
		exit(1);
	}
	pthread_create(&tid,NULL,tfn,NULL);
	while(1){
		pthread_mutex_lock(&mutex);
		printf("HELL0 ");
		sleep(rand()%3);
		printf("WORLD\n");
		pthread_mutex_unlock(&mutex);
		sleep(rand()%3);
	}
    pthread_join(tid,NULL);
	pthread_mutex_destroy(&mutex); //销毁互斥锁
	return 0;

}
           

继续阅读