【发布时间】:2025-12-06 19:10:01
【问题描述】:
在一个简单的 MFC 应用程序中,我需要一个工作线程来不断轮询 ioctl 以获取事件。起初,我尝试在 while 循环中使用非重叠 ioctl 来实现这一点。我认为的方式是,如果 ioctl 没有立即完成 io 请求,线程会将控制或上下文切换转移到另一个线程(主线程或 MFC 消息控制循环),而是锁定应用程序。
在第二次尝试中,我使用了重叠,问题就消失了。但在我看来,这两种方法在行为上是相同的,因为我使用 WaitForSingleObject 等待事件(io 请求完成)触发。
基本布局如下。请注意,以下代码不完整,仅显示构造
同步:
WaitForIo {
do {
DeviceIoControl(hDevice,ioctl_code, ..., NULL);
do something after io request completed
} while(1);
return;
}
异步:
WaitForIo {
do {
Overlapped ov;
//CreateEvent
DeviceIoControl(hDevice,ioctl_code, ..., &ov);
WaitForSingleObject
do something after io request completed
} while(1);
}
为什么这两种方法的行为不同?我的逻辑有问题吗?
【问题讨论】:
-
他们的行为有何不同?
-
一个锁定应用,另一个不锁定
-
我希望您发布真实代码,而不是这种伪代码废话。不过我冒险猜测一下:在第二个 sn-p 中,您没有使用
FILE_FLAG_OVERLAPPED打开设备,&ov参数被忽略,事件永远不会收到信号并且等待永远不会满足,离开线程永远冻结,不消耗 CPU 时间。 -
另外,“它锁定应用程序”到底是什么意思?在我的计算机上,如果线程运行时间过长,线程会被抢占。
-
I 使用重叠结构的方法不会锁定第一种方法(同步),并且 hDevice 是使用 FILE_FLAG_OVERLAPPED 创建的。