线程间的同步与互斥技术,主要以互斥锁和条件变量为主,条件变量和互斥锁的配合使用可以很好的处理对于条件等待的线程间的同步问题。
我们先来认识几个关于条件变量的函数:
和Mutex的初始化和销毁类似,pthread_cond_init用来初始化一个条件变量,attr参数为NULL,表示属性为缺省值。
pthread_cond_destroy表示销毁一个条件变量。
如果条件变量是静态分配的,就可以用宏定义来初始化。
成功返回0,失败返回相应的错误码。
一个线程可以调用pthread_cond_wait来阻塞等待,从函数原型可以看出,互斥锁和条件变量是“黄金搭档”!wait函数做以下三个步骤:
1. 释放Mutex。
2. 阻塞等待。
3. 当被唤醒时,重新获得Mutex并且返回。
pthread_cond_timewait函数还有一个abstime是自己设定的一个等待时间。
pthread_cond_signal用来一次唤醒一个进程,pthread_cond_broadcast用来一次唤醒所有进程。
我们来模拟一个生产者——消费者模型。在该例子中,我们用单链表来实现“交易场所”,生产者用来给单链表里放数据,然后去唤醒挂起的消费者,消
费者用来当链表不为空时从里面取数据,为空时消费者就去wait,他们之间维持着互斥与同步的关系。
对于互斥锁和条件变量使用不正确就会产生死锁,死锁也就是,当两个线程已经各自获得一个锁,还需要对方获得的锁才能执行,然而两个锁又在互相占
用着,它们永远处于挂起状态,就成了死锁。
死锁产生的原因:
1. 因为系统资源不足。
2. 进程推进的顺序不合适。
3. 资源分配不恰当。
产生死锁的四个必要条件:
1. 互斥条件:一个资源每次只能被一个进程使用。
2. 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
3. 不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺。
4. 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源。
只要系统发生死锁,上述条件必然成立,而只要上述条件之一不满足,就不会发生死锁。
处理死锁的策略:
1. 检测死锁并且恢复。
2. 对资源进行合理的动态分配。
3. 破除死锁之一的条件来避免死锁。
4. 如果可以通过不申请锁来解决问题,那就尽量避免使用锁。