多线程的同步和互斥
多线程的同步和互斥
一、互斥锁的概念
为了实现线程对资源的合理访问,并且在访问的过程中不会出现线程竞争的情况,Linux系统就提供了一种实现互斥机制的方案,就是互斥锁
互斥锁的本质是一个二值信号量,任何一条线程要开始运行互斥区间的代码,都必须先获取互斥锁,如果其中一条线程抢先获取了互斥锁之后,其余线程就无法再次获取了,相当于给相关的资源加了把锁,直到使用者主动解锁,其余线程方可有机会获取这把锁。
二、互斥锁的使用
(1) 初始化互斥锁
可以看到,Linux系统中提供了一个叫做pthread_mutex_init函数接口,用户利用该函数就可以对互斥量进行初始化,注意:没有经过初始化的互斥量是不能直接使用的!
互斥量的本质就是一个变量,变量的类型是pthread_mutex_t,要注意对该变量的赋值,需要赋值为PTHREAD_MUTEX_INITIALIZER,再去调用pthread_mutex_init()即可。
当然,除了调用函数接口实现互斥锁的初始化之外,用户也可以直接定义一个全局变量,这样其他线程都可以使用互斥锁,但是记得对变量进行初始化为PTHREAD_MUTEX_INITIALIZER。
(2) 上锁解锁操作
int pthread_mutex_lock(pthread_mutex_t *mutex);//上锁,失败则阻塞
int pthread_mutex_trylock(pthread_mutex_t *mutex);//尝试上锁,失败则退出
int pthread_mutex_unlock(pthread_mutex_t *mutex);//解锁
注意:不要在同一个线程中对已经上锁的互斥量重新上锁,这样会导致死锁出现,应该避免该情况出现,上锁之后应该在使用完资源后及时进行解锁。
(3)练习
练习:创建一个进程,在主线程中创建一个子线程,主线程和子线程都会使用相同的临界资源(全局变量),要求线程之前使用互斥锁实现资源的互斥访问。
#include <pthread.h>
#include <stdio.h>
//全局变量
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int a =0;
//线程A
void *task(void *arg)
{
//1.上锁
pthread_mutex_lock(&mutex);
//2.访问
a=2;
printf("I am thread,a=%d\n",a);
//3.解锁
pthread_mutex_unlock(&mutex);
}
int main()
{
//1.创建线程
pthread_t thread;
pthread_create(thread,NULL,task,NULL);
//2.初始化信号量
pthread_mutex_init(&mutex,NULL);
while(1)
{
//1.上锁
pthread_mutex_lock(&mutex);
//2.访问
a=1;
printf("I am main thread,a=%d\n",a);
//3.解锁
pthread_mutex_unlock(&mutex);
}
return 0;
}

浙公网安备 33010602011771号