使用 I/O 完成端口的异步操作返回传输的 0 字节

发布于 2024-08-08 10:01:35 字数 758 浏览 5 评论 0原文

尽管 I/O 操作按预期工作(我的读取缓冲区已满),但使用 I/O 完成端口的异步操作返回传输的 0 个字节。

BYTE buffer[1024] = {0};
OVERLAPPED o = {0};
HANDLE file = CreateFile(
    _T("hello.txt"),
    GENERIC_READ,
    FILE_SHARE_READ,
    NULL,
    OPEN_EXISTING,
    FILE_FLAG_OVERLAPPED,
    NULL
);
HANDLE completion_port = CreateIoCompletionPort(
    file,
    NULL,
    0,
    0
);
ReadFile(
    file,
    buffer,
    1024,
    NULL,
    &o
);

在工作线程中:

DWORD numBytes = 0;
LPOVERLAPPED po;
GetQueuedCompletionStatus(
    completion_port,
    &numBytes,
    0,
    &po,
    INFINITE
);
GetOverlappedResult(file, &o, &numBytes, FALSE);

两个函数都返回 numBytes 中的 0 字节,但 buffer 正在填充。这是预期的行为吗?

谢谢。

Asynchronous operations with I/O Completion Ports return 0 bytes transferred, although the I/O operations work as expected (my read buffers become full).

BYTE buffer[1024] = {0};
OVERLAPPED o = {0};
HANDLE file = CreateFile(
    _T("hello.txt"),
    GENERIC_READ,
    FILE_SHARE_READ,
    NULL,
    OPEN_EXISTING,
    FILE_FLAG_OVERLAPPED,
    NULL
);
HANDLE completion_port = CreateIoCompletionPort(
    file,
    NULL,
    0,
    0
);
ReadFile(
    file,
    buffer,
    1024,
    NULL,
    &o
);

In the work thread:

DWORD numBytes = 0;
LPOVERLAPPED po;
GetQueuedCompletionStatus(
    completion_port,
    &numBytes,
    0,
    &po,
    INFINITE
);
GetOverlappedResult(file, &o, &numBytes, FALSE);

Both functions return 0 bytes in numBytes, but buffer is filling. Is this expected behaviour?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

z祗昰~ 2024-08-15 10:01:35

为了使 GetIoCompletionPort 正常工作,您需要指定一个指向 ULONG_PTR 的非空指针,以便将“key”值写入:

ULONG_PTR key;

GetQueuedCompletionStatus(
    completion_port,
    &numBytes,
    &key,
    &po,
    INFINITE
);

要使用 GetOverlappedResult< /code> 成功,我相信您需要在 OVERLAPPED 结构中指定一个事件句柄(在任何情况下都强烈建议):

o.hEvent = CreateEvent(NULL, FALSE, TRUE, NULL);

像您一样连续调用这两个并没有真正完成太多工作 - 它们两者都告诉你同样的事情。不过,如果您连续调用两者,则需要通过将 CreateEvent 的第三个参数更改为 TRUE,将事件更改为手动重置。我的猜测是,您只是尝试两者,看看是否可以让其中一个工作。考虑到所有因素,我可能只使用 GetQueuedCompletionStatus,然后就这样。当然,您通常要做的不仅仅是调用一次然后退出。您通常在循环中调用它,处理您已读取的当前缓冲区,然后再次调用 ReadFile 来读取另一个信息缓冲区,如下所示:

DWORD numBytes;
LPOVERLAPPED po;
while (GetQueuedCompletionStatus(completion_port, &numBytes, &key, &po, INFINITE)) {
    std::cout << "\rRead: " << numBytes; // just to show it's set correctly.
    process(buffer);
    po->offset += sizeof(buffer);
    ReadFile(file, buffer, sizeof(buffer), NULL, po);
}

至少在我的机器上进行快速测试,这显示正确读取的字节数(sizeof(buffer) 直到最后一个数据包,然后是文件的剩余大小)。

For GetIoCompletionPort to work correctly, you need to specify a non-null pointer to a ULONG_PTR for it to write the 'key' value to:

ULONG_PTR key;

GetQueuedCompletionStatus(
    completion_port,
    &numBytes,
    &key,
    &po,
    INFINITE
);

To use GetOverlappedResult successfully, I believe you need to specify an event handle in the OVERLAPPED structure (strongly recommended in any case):

o.hEvent = CreateEvent(NULL, FALSE, TRUE, NULL);

Calling the two in succession as you were doesn't really accomplish much -- they both tell you about the same things. Though if you do call both in succession, you'll need to change the Event to be a manual-reset by changing the third parameter to CreateEvent to TRUE. My guess is that you were just trying both to see if you could get one to work. All things considered, I'd probably just use GetQueuedCompletionStatus, and leave it at that. Of course, you'll usually do more than call it once and quit. You normally call it in a loop, processing the current buffer you've read, then calling ReadFile again to read another buffer of info, something like this:

DWORD numBytes;
LPOVERLAPPED po;
while (GetQueuedCompletionStatus(completion_port, &numBytes, &key, &po, INFINITE)) {
    std::cout << "\rRead: " << numBytes; // just to show it's set correctly.
    process(buffer);
    po->offset += sizeof(buffer);
    ReadFile(file, buffer, sizeof(buffer), NULL, po);
}

At least in a quick test on my machine, this showed the number of bytes read correctly (sizeof(buffer) up to the last packet, then the remaining size of the file).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文