条件变量是线程同步的一种方式
抛出问题:线程同步与进程间通信的关系?
两者实际都是指消息的传递。然而同个进程的不同线程除各自栈资源共享进程的资源, 在进行消息传递时需要进行互斥处理(加锁)--因此加了个特殊概念-线程同步
线程常用同步方式:信号量(PV操作)>互斥量(互斥锁)>读写锁,条件变量
信号量:可以看作是锁,m个线程拿n个锁
互斥量:互斥锁,多个线程拿1个锁
读写锁:粒度更细的互斥锁,为了效率
使用锁:当线程拿不到锁被阻塞,线程不会休眠,线程会循环尝试拿锁,消耗cpu。 倘若线程拿不到锁时,令线程休眠(意味着线程阻塞),在可以拿到锁的条件下,有个信号通知该线程,唤醒线程拿锁工作,则可以更省cpu,而这个信号就是条件变量。
条件变量的使用 条件变量是需要配合锁使用的,因为存在着共享资源,必然需要对共享资源进行互斥保护处理;特殊的是使用了条件变量后则阻塞线程进入休眠,后续等条件变量的通知来唤醒。
条件变量的使用有两种常用使用场景:
1:多个线程竞争同个资源的步骤
mutex.Lock()//加锁
//判断资源是否准备好了,若资源未准备好,则进入休眠等通知
for ready != true {
cond.Wait()
}
//伪代码,资源准备好了,则对资源进行操作
Do()
//操作完后则让出资源 ready = true
mutex.UnLock()
//操作完了,让其资源使用权,通知信号给其它休眠线程
cond.Signal()
2:a线程作为生产者生产消息,b线程作为消费者消费消息
生产者:message作为消息载体
mutex.Lock()
//判断消息载体是否为空,若不为空,说明有其它线程占用了消息载体,则休眠等消息(sendCond)通知
for message != null {
sendCond.Wait()
}
//若消息载体不为空,则生产消息。
producer.Do() //完成后则message != null了
message != null
mutex.Unlock()
//通知消费者可以消费信息了
recvCond.Signal()
*消费者: *
mutex.Lock()
//判断消息载体是否为空,若为空,说明有其它线程占用了消息载体,则休眠等消息(recvCond)通知
for message == null {
recvCond.Wait()
}
//若消息不为空,则消费信息
consumer.Do() //完成后则message == null了
message == null
mutex.Unlock()
//通知生产者继续生产信息
sendCond.Signal()