gpt4 book ai didi

multithreading - Win32 : ReadFileEx() on STD_IN_HANDLE blocks, 为什么?

转载 作者:行者123 更新时间:2023-12-03 00:24:43 25 4
gpt4 key购买 nike

我正在尝试使用 Win32 API 创建一个子线程,该子线程从 STD_INPUT_HANDLE 读取并将其读取的字节推送到套接字中。因为我希望在退出时能够安全地关闭该线程,所以我使用 ReadFileEx() 和重叠 I/O,而不是普通的旧阻塞 ReadFile()。我的想法是,我的线程将在 WaitForSingleObject() 而不是 ReadFile() 中等待,当主线程希望从属线程消失时,它将在该对象上发出信号,从属线程将唤醒并退出,然后主线程可以继续其关闭序列。

我的问题是这样的:尽管文档说 ReadFileEx() 是异步的,因此永远不会阻塞...我的从属线程仍然在 ReadFileEx() 内阻塞。 (我在事件循环中插入了 printf 来验证它在哪里阻塞)因此,我的主线程无法关闭从属线程,因此主程序永远不会退出。

我做错了什么,还是 ReadFileEx() 在从标准输入读取时会阻塞?如果是后者,线程关闭问题的解决办法是什么?从属线程的入口函数如下,供您个人...

[... in the main thread, before the slave thread is spawned...]
_stdinHandle = GetStdHandle(STD_INPUT_HANDLE);
_wakeupSignal = CreateEvent(0, false, false, 0);
[...]

VOID WINAPI CompletedReadRoutine(DWORD dwErr, DWORD cbBytesRead, LPOVERLAPPED lpOverLap)
{
printf("CompletedReadRoutine dwErr=%li cbBytesRead=%li overlap=%p\n", dwErr, cbBytesRead, lpOverLap);
}

void StdinDataIO :: IOThreadEntry()
{
char buf[4096];
OVERLAPPED olap;
bool keepGoing = true;
bool overlappedReadPending = false;
while(keepGoing)
{
if (overlappedReadPending)
{
DWORD waitResult = WaitForSingleObjectEx(_wakeupSignal, INFINITE, true);
switch(waitResult)
{
case WAIT_IO_COMPLETION:
{
overlappedReadPending = false;
DWORD numBytesRead;
if ((GetOverlappedResult(_stdinHandle, &olap, &numBytesRead, true) == false)||(SendData(_slaveSocket, buf, numBytesRead, true) != numBytesRead)) keepGoing = false;
}
break;

default:
keepGoing = false;
break;
}
}
else
{
memset(&olap, 0, sizeof(olap));
if (ReadFileEx(_stdinHandle, buf, sizeof(buf), &olap, CompletedReadRoutine)) overlappedReadPending = true;
else keepGoing = false;
}
}
if (overlappedReadPending) CancelIo(_stdinHandle);
_slaveSocket.Reset(); // this alerts the main thread that we are gone
}

最佳答案

来自 ReadFileEx 的文档描述您可以传入哪种文件句柄:

This file handle must have been created with the FILE_FLAG_OVERLAPPED flag and must have the GENERIC_READ access right.

否则,当您使用未使用FILE_FLAG_OVERLAPPED打开的句柄调用ReadFileEx时,ReadFileEx将会阻塞。

您也可以在 GetStdHandle 返回的句柄上调用 WaitForSingleObject 或其他同步函数,并调用 _kbhit 或控制台事件的其他组合如果您想确保有可用的输入,请进行处理。

关于multithreading - Win32 : ReadFileEx() on STD_IN_HANDLE blocks, 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1315156/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com