线程同步之条件变量

来源:互联网 发布:mac os 显示器刷新率 编辑:程序博客网 时间:2024/04/19 14:53

一、引言

假设有一个任务,由我和张三共同完成。张三把寄来的文稿初步审阅后放入一个队列,我负责将这个队列中的文稿进行审批,决定刊登与否。张三审阅一份文稿需要15分钟,我处理一个文稿需要2分钟。

如果将张三和我看作两个线程,那么我们共享一个队列的数据。按照一般的多线程思路,他每隔一段时间往队列中放入数据,我每隔一段时间检查一下队列中是否有数据,若有,则处理之。

若我们按照上面的方式工作,则大部分的时间,我只是在干等着,所以,这是一种比较低效的方式。

但换一种方式之后,情况就好很多了。他每把一个文稿放入队列,就检查一下队列中的文稿数量是否达到20,若达到,则通知我来处理。我来进行处理之后,由于我的处理速度更快,所以一段时间之后,队列会变空,我便离开。这样,我就可以把时间更有效率的利用起来,例如,利用空余的时间打扫卫生、整理文件或做一些其他的事情。

有些时候,我们不应让一个线程“忙等”,而是应让它休眠(sleep)以节省计算机资源,直到一个条件满足之后,再继续工作。

利用条件变量就可以达到上述目的。

条件变量有两个状态:成立不成立


二、初始化

在使用条件变量之前,需要定义一个CONDITION_VARIABLE类型的变量:

?
1
CONDITION_VARIABLE cv;

与条件变量有关的函数有5个;

?
1
2
3
4
5
InitializeConditionVariable
SleepConditionVariableCS
SleepConditionVariableSRW
WakeConditionVariable
WakeAllConditionVariable

对条件变量,不能在代码中直接进行读、写,所有的操作必须通过上述函数进行

条件变量在使用之前必须进行初始化,方法是:

?
1
InitializeConditionVariable(&cv);

在程序不再需要条件变量时,不需要手动销毁它。


三、等待

等待条件变量可以用SleepConditionVariableCS或SleepConditionVariableSRW函数。

?
1
SleepConditionVariableCS(&cv, &cs, dwTimeout);

第一个参数是条件变量的指针,第二个参数是临界区(CRITICAL_SECTION)指针,第三个参数是超时,单位:毫秒。

这个函数的作用是,解锁cs并等待cv成立,函数返回之后,会将cs重新锁上,并将cs设为不成立。在等待期间,当前线程会休眠,直到它被唤醒(见后面介绍的用来唤醒的函数)。

SleepConditionVariableSRW用法与之类似,详见这里:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms686304.aspx


四、通知(唤醒)

?
1
WakeConditionVariable(&cv);

用WakeConditionVariable将cv的状态设为成立,并唤醒正在等待cv的那些线程中的一个。

?
1
WakeAllConditionVariable(&cv);

用WakeAllConditionVariable将cv的状态设为成立,并唤醒所有的正在等待cv的那些线程。

0 0
原创粉丝点击