如果使用 IOCP 进行基本信号传输,传递给 CreateIoCompletionPort 的句柄是什么?

Which handle to pass to CreateIoCompletionPort, if using IOCP for basic signaling?

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

Consider using PostQueueCompletionStatus rather than SetEvent API. The latter boosts the target thread’s priority by 1 which may cause it to preempt something else.

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

原因是我希望生产者线程成为 background/low 优先线程,但是 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);

但它只是 returns NULL。

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

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

FileHandle [in]

An open file handle or INVALID_HANDLE_VALUE.

  • The handle must be to an object that supports overlapped I/O.

  • If a handle is provided, it has to have been opened for overlapped I/O completion. For example, you must specify the FILE_FLAG_OVERLAPPED flag when using the CreateFile function to obtain the handle.

  • If INVALID_HANDLE_VALUE is specified, the function creates an I/O completion port without associating it with a file handle. In this case, the ExistingCompletionPort parameter must be NULL and the CompletionKey parameter is ignored.