转载自:万一的博客
之前已经有了两种线程同步的方法:
CriticalSection(临界区)和Mutex(互斥)吗,这两种同步方法差不多,只是作用域不同
CriticalSection类似于只有一个蹲位的公共厕所,只能一个个地进
Mutex 对象类似于接力赛中的接力棒,某一时刻只能有一个人持有,谁拿着谁跑
什么是Semaphore(信号或叫信号量)呢?
譬如到银行办业务、或者到车站买票,原来只有一个服务员,不管有多少人排队等候,业务只能一个个地来
假如增加业务窗口,可以同时受理几个业务呢?
这就类似于Semaphore 对象,Semaphore 可以同时处理等待函数(如:WaitForSingleObject)申请的线程
Semaphore 的工作思路如下:
1. 首先要通过 CreateSemaphore(安全设置, 初始信号量, 信号总数, 信号名称) 建立信号对象
参数四:和Mutex一样,它可以有个名称,也可以没有,本例中就没有(nil);有名称的一般用于跨进程
参数三:信号总数,是Semaphore最大处理能力,就像银行一共有多少个业务窗口一样
参数二:初始信号量,这就像银行的业务窗口很多,但打开几个可不一定,如果没打开和没有一样
参数一:安全设置和前面一样,使用默认(nil)即可
2. 要接受Semaphore 服务(或叫协调)的线程,同样需要等待函数(如:WaitForSingleObject)排队等候
3. 当一个线程使用完一个信号,应该用 ReleaseSemaphore(信号句柄, 1, nil) 让出可用信号给其他线程
参数三:一般是nil,如果给数字指针,可以接受到此时(之前)总共闲置多少个信号
参数二:一般是1,表示增加可用信号
如果要增加CreateSemaphore 时的初始信号,也可以通过 ReleaseSemaphore
4. 最后,作为系统内核对象,要用 CloseHandle关闭
另外,在 Semaphore 的总数为 1的情况下,就和 Mutex(互斥)一样了
在本例中,每点击按钮,将建立一个信号总数为 5 的信号对象,初始信号来自 Edit1;同时有 5 个线程去排队。
本例也附上了 Delphi中 TSemaphore类的例子,但是没有过多纠结于细节,是为了尽快理出多线程的整体思路