完成端口上的WaitForSingleObject()?
今天笔者了解到,我可以打电话CreateIoCompletionPort()
,然后通过返回HANDLE
到WaitForSingleObject()
:完成端口上的WaitForSingleObject()?
#include <Windows.h>
int main()
{
HANDLE h = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 0);
auto bRes = PostQueuedCompletionStatus(h, 1, 2, 0);
if (!bRes) {
abort();
}
auto dwRes = WaitForSingleObject(h, INFINITE);
if (dwRes != WAIT_OBJECT_0){
abort();
}
LPOVERLAPPED pOvr;
DWORD cb;
ULONG_PTR key;
bRes = GetQueuedCompletionStatus(
h, &cb, &key, &pOvr, INFINITE); // <-- returns 1, 2, nullptr
if (!bRes) {
abort();
}
dwRes = WaitForSingleObject(h, INFINITE); // <-- blocks here
return 0;
}
它工作在我的Windows 10盒预期。
这样的行为是已知的还是合法的或有记录的?我无法找到任何有关它的信息。
如果你读了WaitForSingleObject()
documentation,一个I/O完成端口是不允许的手柄类型:
的
WaitForSingleObject
功能可以等待以下对象:
- 更改通知
- 控制台输入
- 事件
- 内存资源通知
- 互斥
- 过程
- 信号灯
- 螺纹
- 可等待计时器
等待完成事件的端口上到达,你必须通过手柄到GetQueuedCompletionStatus()
本身,并让它阻塞,直到事件到达或超时发生。
#include <Windows.h>
int main()
{
HANDLE h = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 0);
auto bRes = PostQueuedCompletionStatus(h, 1, 2, 0);
if (!bRes) {
abort();
}
LPOVERLAPPED pOvr;
DWORD cb;
ULONG_PTR key;
bRes = GetQueuedCompletionStatus(
h, &cb, &key, &pOvr, INFINITE); // <-- returns 1, 2, nullptr
if (!bRes) {
abort();
}
bRes = GetQueuedCompletionStatus(
h, &cb, &key, &pOvr, INFINITE); // <-- blocks here
return 0;
}
感谢您的及时响应:-) WaitForSingleObject()可以等待文件句柄,虽然在WaitForSingleObject()的文档中没有明确提到它(请参阅https://blogs.msdn.microsoft.com/oldnewthing/20121012-00/?p=6343,“一个文件句柄是一个可等待的对象“)。 我完全知道正确使用完成端口。我想知道一个竣工港是否也是一个等待的对象。 –
['GetOverlappedResult()'](https://msdn.microsoft.com/en-us/library/windows/desktop/ms683209.aspx)的文档提到一个文件,命名管道和通信设备句柄也是可以处理,但不鼓励直接等待。但[I/O完成端口文档](https://msdn.microsoft.com/en-us/library/windows/desktop/aa365198.aspx)中没有提到I/O完成端口句柄直接等待。如果没有记录,请不要依赖它。 –
摘要:
- 不这样做。请参阅Remy Lebeau的答案和MSDN,了解如何正确使用完成端口。
- 这样滥用完井港不仅没有证件,而且也不可靠。行为因Windows 10的版本而异。
- 完成端口可能是内核中等待的合法对象,因为支持完成端口的KQUEUE具有DISPATCHER_HEADER。
'dwRes = WaitForSingleObject(h,INFINITE); // RbMm
是的。在等待状态和源代码崩溃转储在这里:https://1drv.ms/f/s!AtyOp6RRifUTuC2CAVzWdFrvZu6w –
是的,在win10真的等待KQUEUE调度头。但在win8.1中说 - 不。 – RbMm