如果使用 IOCP 进行基本信令,哪个句柄传递给 CreateIoCompletionPort?

Posted

技术标签:

【中文标题】如果使用 IOCP 进行基本信令,哪个句柄传递给 CreateIoCompletionPort?【英文标题】:Which handle to pass to CreateIoCompletionPort, if using IOCP for basic signaling? 【发布时间】:2018-12-06 12:23:20 【问题描述】:

背景:如本文所述,Designing Applications for High Performance:

考虑使用PostQueueCompletionStatus 而不是SetEvent API。后者将目标线程的优先级提高 1,这可能会导致它抢占其他东西。

我在 Windows 上使用 C 语言工作,我想将生产者/消费者 fifo 中的信号从 SetEvent/WaitForSingleObject 替换为 IO 完成端口。

原因是我希望生产者线程成为后台/低优先级线程,但SetEvent 总是提升消费者线程并且经常挂起我的生产者线程,我想避免这种情况以满足某些延迟要求。

这些方法的测试表明,在使用 SetEvent 通知消费者线程之后,我会时不时地在生产者线程中得到大约 50 微秒的延迟,所以如果这是一个便宜的替代品,我想我可能会试一试。

短版:我想切换这样的东西

void Produce(int some_item)

    Enqueue(some_item);
    SetEvent(hndEvent);


void Consume(void)

    while (true) 
    
        if (WaitForSingleObject(hndEvent, INFINITE) == WAIT_OBJECT_0)
        
            // consume
        
    

我猜是这样的:

void Produce(int some_item)

    Enqueue(some_item);

    unsigned long evt = 1; // "item enqueued"
    PostQueuedCompletionStatus(hndIOCP, 0, evt, NULL);


void Consume(void)

    while (true) 
    
        unsigned long evt;
        LPOVERLAPPED ovlp;
        if (!GetQueuedCompletionStatus(hndIOCP, NULL, &evt, &ovlp, INFINITE))
            break;

        // consume
    

但由于我没有将这个 IOCP 用于信号以外的任何事情,我应该将什么句柄传递给 CreateIoCompletionPort

我想我会简单地做这样的事情:

// single thread IOCP
hndIOCP = CreateIoCompletionPort(NULL, NULL, 0, 1);

但它只返回 NULL。

【问题讨论】:

【参考方案1】:

我找到了答案,我错过了CreateIoCompletionPort 文档中的以下部分。

第一个参数是FileHandle,如果不使用它必须设置为INVALID_HANDLE_VALUE而不是零。

FileHandle [in]

打开的文件句柄或INVALID_HANDLE_VALUE

句柄必须指向支持重叠 I/O 的对象。

如果提供了句柄,则必须为重叠 I/O 完成打开它。例如,使用CreateFile函数获取句柄时,必须指定FILE_FLAG_OVERLAPPED标志。

如果指定了 INVALID_HANDLE_VALUE,该函数将创建一个 I/O 完成端口,而不将其与文件句柄相关联。在这种情况下,ExistingCompletionPort 参数必须为 NULL,而 CompletionKey 参数将被忽略。

【讨论】:

以上是关于如果使用 IOCP 进行基本信令,哪个句柄传递给 CreateIoCompletionPort?的主要内容,如果未能解决你的问题,请参考以下文章

带有任务调度程序的 IOCP(线程构建块)

Win32:不可能将 iocp 与标准输入句柄一起使用

python 怎么把一个类传递给JAVA,然后Java调用python类的回调函数

如何使用 IOCP 将用户定义的数据传递给工作线程?

如何在 C 中打开数据库句柄并使用 SWIG 将其传递给 Perl?

如果在 IOCP 模型中指定了 WSASend 的 lpCompletionRoutine 怎么办?