工作线程中的同步与异步 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的主要内容,如果未能解决你的问题,请参考以下文章

Jsp页面中的异步与同步

同步与异步的区别

并发与并行同步与异步,线程安全的实现

并发与并行同步与异步,线程安全的实现

并发与并行同步与异步,线程安全的实现

并发与并行同步与异步,线程安全的实现