现在的位置: 首页 > 综合 > 正文

win32多线程程序设计笔记(第四章下)

2018年10月01日 ⁄ 综合 ⁄ 共 1610字 ⁄ 字号 评论关闭

上一笔记讲了同步机制中的临界区域(Critical Sections)、互斥器(Mutexes),下面介绍同步机制中的另外两种。

信号量(Semaphores)

举个例子

        现在有人要租车,接待他的代理人发现还有3辆车可以用,但正在给他办理手续的时候发现还有三个人也在做同样的动作。现在,就是有四个人想租三辆车。

        我们写个程序解决租车问题,方法一就是为每辆车都加一个mutex保护,问题是如果是一家大型出租车公司就需要有成百上千的mutexes了。方法二使用单一的mutex为所有的车辆服务,但一次只能有一个店员出租,这样问题就是客户会减少。

解决

      现在我们将所有的车视为相同,车交到客户手上之前,唯一需要知道的就是现在有几辆车可以用,我们用semaphore来维护这个数字,每一个锁定动作成功,semaphore的现值就会减1。

注意:与mutex不同的是,调用ReleaseSemaphore()的那个线程,并不一定就得是调用wait...()的那个线程。任何线程都可以在任何时间调用ReleaseSemaphore(),解除被任何线程锁定的semaphore。

事件(Event)

//复习

       从第三章以来,每章都讲到了一个重要的函数,就是Wait...()系列函数。

       第三章判断一个线程是否结束:WaitForSingleObject(HANDLE hthred,...);

       第四章中判断是否能够进入锁住互斥器:WatiForSingleObject(hMutex,...);

       Wait...()函数会在核心对象被激发时返回。对于hthred而言,线程结束,意味着核心对象被激发;对于hMutex而言, hMutex不再被其它任何线程使用,意味着核心对象被激发。反正对于各种核心对象而言,一定是有某种场景的出现使得核心对象被激发,除了Event这个核心对象

===============================================


        对于Event这个核心对象而言,它的激发状态完全由程序来控制,也就是说,由自己来控制Event的激发或未激发状态( 通过SetEvent() , ResetEvent() )。当线程1因调用Wait…(hEvent)而被阻塞后,一定是某个线程调用了SetEvent(
hEvent )使hEvent被设为激发状态,从而使线程1被解除阻塞继续向下运行,具体的运用参见下表:
(使用CreateEvent ()函数构造Event核心对象,CreateEvent ()的第二个参数决定了产生的Event对象是Manual(手工)方式还是Auto(自动)方式;第三个参数决定了决定了产生的Event对象初始状态是激发还是未激发)  

   

函数
EVENT对象[Manual方式产生]
EVENT对象[Auto方式产生]
Wait…()
EVENT对象变为激发状态(使得因调用Wait…()而等待的线程被唤醒)之后,不会被重置为非激发状态(必须调用ResetEvent()) EVENT对象变为激发状态(使得因调用Wait…()而等待的线程被唤醒)之后,自动重置为非激发状态
SetEvent() EVENT对象设为激发状态 EVENT对象设为激发状态
ResetEvent() EVENT对象设为非激发状态 EVENT对象设为非激发状态
PulseEvent() EVENT对象设为激发状态,唤醒“所有”等待中的线程,然后把EVENT对象设为非激发状态
EVENT对象设为激发状态,唤醒“一个”等待中的线程,然后把EVENT对象设为非激发状态

注意Event核心对象的不同的状态(初始状态是激发还是未激发)及不同的类型(Manual[手工]方式还是Auto[自动]),与之对应的处理方式也就不一样,情况太多了真是不好一一举例,以后补上J(在下面第五章中,我举了一个例子)

抱歉!评论已关闭.