Windows Via C/C++:内核模式下的用户同步——成功等待的副作用

对某些内核对象,成功调用WaitForSingleObject/WaitForMultipleObjects时对象的状态会自动改变。“成功调用”是指WaitForXXX函数返回WAIT_OBJECT_0相关的值,函数返回值是WAIT_TIMEOUT或WAIT_FAILED时,内核对象的状态不会发生任何变化。

我把对象的状态因成功调用Wait函数而改变称之为“成功等待的副作用” (successful wait side effect)。比如线程正在等待一个自动重置的事件对象(auto-reset event object),当事件对象变成signaled后,Wait函数会向正在等待的线程返回WAIT_OBJECT_0,就在Wait返回之前,事件对象的状态会被自动重置为nonsignaled——这就是成功等待的副作用。不同的内核对象在Wait成功调用会出现不同的副作用,有一些内核对象完全没有副作用,比如进程和线程对象——成功等待这些对象并不会改变其状态。

Wait函数的操作是原子的,比如当线程调用WaitForMultipleObjects时,函数会检测所等待对象的状态,如有需要在等待成功时重置对象的状态——这一切都是原子的。比如有两个线程T1和T2同时执行下面的代码:

HANDLE h[2];
h[0] = hAutoResetEvent1; // Initially nonsignaled
h[1] = hAutoResetEvent2; // Initially nonsignaled
WaitForMultipleObjects(2, h, TRUE, INFINITE);

初始时,两个事件对象均为nonsignaled状态,因此T1和T2均被挂起。假设过了一段时间后,hAutoResetEvent1变为signaled,两个线程都会检测到这一变化,但由于hAutoResetEvent2仍旧是nonsignaled,T1和T2会继续等待,此时Wait调用尚未成功返回,因此hAutoResetEvent1并不会被自动重置。接下来,hAutoResetEvent2变为signaled,T1和T2中的某个线程将检测到两个对象的状态均变为signaled,然后该线程的Wait函数将两个对象的状态重置为nonsignaled后返回——这便是成功等待的副作用,而另一线程将发现两个对象的状态均变成了nonsignaled,因此它会继续等待。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值