******* 线程互斥与同步大讨论, 有经验的高手请进 *******
我们知道在NT系统下,为了方便程序员实现线程间的互斥与同步,系统提供了三个核心对象:
(1)互斥量
(2)信号量
(3)事件
还有一个非系统核心对象为:
(4)临界区(不能用于进程间的同步)
通过对它们的组合调用,我们很容易满足平时的一般需求,达到同步与互斥的目的.但有时我
们也会发现利用它们很难达到我们要求的同步目的或即使能实现也很复杂. 例如说:对一个
队列或数组实施同步(典型读者写者问题).
我们平时为了简便可以这样做: 把队列数据封装
一个类, 利用临界区互斥, 再加一个整型变量表示队列中数据元素的个数. 这样我们读线程
就可以来轮循它, 当>0时,取一个元素, 否则返回失败; 写线程呢? <最大值时, 写一个元素,
否则返回失败. 当然这样实现同步,它效率低, 因为你要不断地去轮循并检测它.
因此,我们有时经常加一个事件来通知, 这个事件有信号表示队列中有元素,否则无元素,
读线程首先WaitForSingleObject(...), 写线程呢?写完一个元素后如果需要的话则调用
SetEvent(...). 这样虽然能达到较好的性能改善作用. 但它仍不理想, 有可能通知并不及时.
为了达到最理能效果,我们实际上必须要为每个元素设置一个事件(假如这个队列或数组的维数为10,
我们就必须设置10个事件), 这样,每个元素的位置是否有元素,我们可以根据这个event唯一确定.
但这样做对我们来说实在太复杂,而且对同时有多个读线程多个写线程时, 很容易出错并死锁.
所以,我们在实际编程中有这种需求,那就是我们面对很复杂的同步与互斥问题,我们更喜欢通过
调用PV操作(学操作系统时,大家肯定特别熟悉)来实现同步. 其实PV操作解决这些复杂同步问题时,
它往往更显得简单明了,你认为呢?
但现在问题就是: NT系统并没有这种PV操作接口通过API提供给我们. 那我们该怎样获得这种接口或
自己封装PV操作.
例如:在java中, 我就很容易地封装了一个这样的提供PV操作的类,如下(可在C++中,我们却难于做到):