如果使用 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.
背景:如本文所述,Designing Applications for High Performance:
Consider using
PostQueueCompletionStatus
rather thanSetEvent
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 theCreateFile
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, theExistingCompletionPort
parameter must beNULL
and theCompletionKey
parameter is ignored.