Win32学习4
13、事件
①通知类型:
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES IpEventAttributes,//SD
BOOL bManualReset, // reset type
BOOL bInitialState, // initial state
LPCTSTR IpName // object name
);
bManualReset 这个成员如果是 TRUE,这个事件就是通知类型,如果这个是 FALSE则就不是。 bInitialState 这个成员代表了是否产生信号。(如WaitForSingleObject 这样的 API ,如果该成员没有产生信号的话,就会一直处于堵塞状态直到产生信号才会接着继续执行。) IpName 这个成员代表了该事件的名字。(如果是当前的进程的使用的话,可以不设置名字,如果是多个进程使用就需要设置名字了。)
如同上方这段测试代码,如果CreateEvent的时候设置没信号,两个线程都不会正常执行,都会变为堵塞状态。如果将其设置为有信号,将会正常执行线程。
如果是通知类型的两个线程都能正常的执行(不会修改对应的状态),而如果设置为互斥类型,一个没执行完毕,另一个便无法正常开始执行。除非第一个线程在执行中执行了SetEvent,即修改对应的状态之后,另一个才能正常的执行。(应用场景即为,如果想要多个线程无法同时执行,就用互斥类型;如果想要多个线程能够执行,需要依次发送一个信号,即为实现线程同步,就用通知类型)
②线程同步
<1>线程互斥:线程互斥是指对于共享的进程系统资源,在各单个线程访问时的排 它性。当有若干个线程都要使用某一共享资源时,任何时刻最多只允许一个线程去 使用,其它要使用该资源的线程必须等待,直到占用资源者释放该资源。 <2>线程同步:线程同步是指线程之间所具有的一种制约关系,一个线程的执行依 赖另一个线程的消息,当它没有得到另一个线程的消息时应等待,直到消息到达时 才被唤醒。
③同步的前提是互斥:
)
互斥是一种无序的概念,即需要满足同一时间仅有一个线程使用该共享资源;而同步即为互斥加上有序,就是当某个线程执行完后,发送信号另一个线程便能够执行,而并非产生只能一个线程无序的不断使用该资源。
可以理解为: 同步 = 互斥 + 有序
线程同步形象的例子就比如:生产者和消费者。利用如下的代码来解释一下为什么利用事件能够更好的实现线程同步。
通过运行上面的这些代码可以发现,当两个线程互斥的时候,是无法同时执行的。但是实际上这样的是有逻辑漏洞的,其并非是有序的。消费者想要消费就必须需要生产者进行生产之后才可以。如果我们利用事件中的通知来实现线程同步,就能够得到一个有序的互斥。