Delphi 多线程之 Semaphore ( 信号对象 )
之前已经有了两种多线程的同步方法
:
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 类的例子 , 但没有过多地纠缠于细节 , 是为了尽快理
出多线程的整体思路 .
--------------------------------------------------------------------------------
本例效果图
:
--------------------------------------------------------------------------------
代码文件
:
--------------------------------------------------------------------------------