条件变量的使用

235 阅读2分钟

条件变量线程同步的一种方式

抛出问题:线程同步与进程间通信的关系

两者实际都是指消息的传递。然而同个进程的不同线程除各自栈资源共享进程的资源, 在进行消息传递时需要进行互斥处理(加锁)--因此加了个特殊概念-线程同步

线程常用同步方式:信号量(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()