VC++ 线程同步之信号量(Semaphore)

VC++ 线程同步之信号量(Semaphore)

信号量与互斥量类似,唯一的区别是多个对象可持有信号量的所有权。假设有一个复杂的数学运算要用到整个逻辑

CPU 核。如果每个核只运行一个线程,计算结果没问题,但是,如果每个核运行多个线程,计算结果就有问题

了。另外,还假设计算过程中所需的线程数量比同时工作的逻辑核的数量多。

最好选择信号量对象来处理这种情况,我们可以把信号量对象的最大值设置为机器的逻辑核数量。当线程数量不超

过核的数量时,它们能同时工作,优化计算过程。当线程数量超过逻辑核的数量时,一些线程将被挂起,等待其他

线程执行完毕。

每次只有一个线程可以获得互斥量,与此不同的是,只要未超过可持有信号量所有权的最大数量,信号量仍然处于

触发状态。如果一个线程要等待信号量,那么在其他线程释放信号量之前它将被挂起。

信号量涉及的函数:

创建或打开一个现有的信号量对象,可以使用CreateSemaphore:

HANDLE WINAPI CreateSemaphore(
    LPSECURITY_ATTRIBUTES  lpSemaphoreAttributes,
    LONG                   lInitialCount,
    LONG                   lMaximumCount,
    LPCTSTR                szName
);

第 1个参数是安全特征,可以指定也可以空出不填(如果不填,该参数将被设为默认值)。第 2个参数没置初始数目以确定信号量的初始触发状态。如果设置为 0,信号量为未触发状态。这个值必须小于第3个参数lMaxmumCount 的值。lMaxmumCount 表示可同时持有信号量所有权的最多对象(线程)数目。必须提供信号量名(szName)。

使用 OpenSemaphore 也可以打开一个现有的信号量:

HANDLE WINAPI OpenSemaphore(
    DWORD    dwDesiredAccess,
    BOOl     bInheritHandle,
    LPCTSTR  szName
);

如果信号量不存在,该例程将失败并返回 NULL。线程操作完毕后,必须释放信号量以递减计数器计数,这样其他

线程才能获得信号量。用 ReleaseSemaphore API 可以释放信号量:

BOOL WINAPI ReleaseSemaphore(
    HANDLE hSemaphore,
    LONG lReleaseCount,
    LPLONG lpPreviousCount
);

这个API有3个参数。第1个参数是之前 CreateSemaphore 或 OpenSemaphore 返回的信号量的句柄。第2个参数

是信号量要递减的对象数量,其值通常是 1,因为线程总是逐个被释放的。有一种情况例外线程 A 获得一个信号

量,然后要创建也需要信号量的线程 B。线程A 在线程B 创建好之前完成了自己的任务,线程B不知道它将被强制

终止,所以线程A要终止子线程且递减信号量为2。

代码示例

以下是使用 Win32API 信号量实现的线程同步代码的完整 C++ 实现。该示例使用两个线程,一个线程在计算 1 到 100 的总和,另一个线程在计算 101 到 200 的总和。在两个线程完成计算后,主线程将这两个部分的总和相加并打印结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值