工作线程中的同步与异步 ioctl
Posted
技术标签:
【中文标题】工作线程中的同步与异步 ioctl【英文标题】:Synchronous vs asynchronous ioctl in worker thread 【发布时间】:2011-09-28 16:39:56 【问题描述】:在一个简单的 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 创建的。
【参考方案1】:
如果它锁定了线程,则意味着您需要通过使其休眠或类似的方式来归还处理器。 WaitForSingleObject 在您调用它时默认会执行此操作。我不确定,但我认为在 DeviceIoControl 函数中放置 null 会使其在保持对线程的控制的同时等待 - 因此会锁定线程。
【讨论】:
以上是关于工作线程中的同步与异步 ioctl的主要内容,如果未能解决你的问题,请参考以下文章