互斥锁和条件变量
产生背景:线程的最大特点是资源共享,在多线程的编程里面,多个线程对于临界变量的修改,就出现了同步问题;互斥锁和条件变量是解决这个问题的常用办法。
互斥锁:
通过锁机制来实现线程间数据的同步,在同一时刻通常只允许一个关键部分的代码。
使用例子:
pthread_mutex_lock (&mutex); //加锁
printf(" a = %d\n", a);
a++;
pthread_mutex_unlock (&mutex);//解锁
中间为:临界数据
在使用之前,要对互斥锁进行初始化:
初始化方式:1、静态赋值法:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITALIZER;
2、使用函数动态赋值法:
int pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr *mutexattr);
互斥锁常用操作函数:
函数 | 功能 |
---|---|
pthread_mutex_init | 初始化 |
pthread_mutex_lock | 加锁,如果不成功,阻塞等待 |
pthread_mutex_unlock | 解锁 |
pthread_mutex_trylock | 测试加锁,不加成则立即返回,错误码为EBUSY |
pthread_mutex_destroy | 注销一个锁 |
1、如果对已经被加锁的锁变量尝试加锁,去尝试加锁的线程就会阻塞(挂起),直到互斥锁被加锁线程解锁。
2、使用pthread_mutex_unlock
解锁的两个条件:互斥锁处于加锁状态;解锁函数必须是给互斥锁加锁的线程。
3、当一个互斥锁使用完成后,必须对它进行清除。(清除互斥锁代表释放它所占的资源)
4、当一个线程试图以另一个线程相反的顺序锁住互斥量的时候,就出现死锁。
条件变量:
条件变量:是利用线程间共享的全局变量进行同步的一种机制
与互斥锁不同,条件变量是用来等待而不是用来上锁的。条件变量用来自动阻塞一个线程,直到某特殊情况发生为止。通常条件变量和互斥锁同时使用。
主要包括两个动作:
一个线程等待”条件变量的条件成立”而挂起;
另一个线程使”条件成立”(给出条件成立信号).
为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起。
条件变量常用操作函数:
函数 | 功能 |
---|---|
pthread_cond_init | 初始化条件变量 |
pthread_cond_wait | 基于条件变量阻塞,无条件等待 |
pthread_cond_timewait | 阻塞到指定事件的发生,计时等待 |
pthread_cond_broadcast | 解除所有线程等待 |
pthread_cond_destroy | 清除条件变量 |
在使用之前,要对条件变量进行初始化:
初始化方式:1、静态赋值法:
pthread_cond_t cond = PTHREAD_COND_INITALIZER;
2、使用函数动态赋值法:
int pthread_cond_init (pthread_cond_t *cond, const pthread_condattr *condattr);(condattr通常是条件变量的属性,由于并没有得到实现,通常值为NULL)
当一个条件变量不再使用的时候,需要将其清除。清除一个条件变量调用pthread_cond_destroy
实现。(只有在没有线程等待该条件变量的时候才能清除这个条件变量)