Multithreading Win32:ReadFileEx()在STD_IN_句柄块上,为什么?
我试图使用Win32 API创建一个子线程,该子线程从STD_输入_句柄读取数据,并将读取的字节推送到套接字中。因为我想在退出时安全地关闭这个线程,所以我使用ReadFileEx()和重叠I/O,而不是普通的阻塞ReadFile()。其思想是,我的线程将在WaitForSingleObject()中等待,而不是在ReadFile()中,当主线程希望从线程离开时,它将在该对象上发出信号,从线程将唤醒并退出,然后主线程可以继续其关闭序列 我的问题是:尽管文档中说ReadFileEx()是异步的,因此永远不会阻塞。。。我的从线程仍在ReadFileEx()内阻塞。(我在事件循环中插入printf以验证阻塞的位置)因此,我的主线程无法关闭从线程,因此主程序永远不会退出 我是否做错了什么,或者ReadFileEx()在读取stdin时是要阻止的?如果是后者,线程关闭问题的解决方案是什么?从线程的输入功能是下面为您的说服Multithreading Win32:ReadFileEx()在STD_IN_句柄块上,为什么?,multithreading,winapi,stdin,Multithreading,Winapi,Stdin,我试图使用Win32 API创建一个子线程,该子线程从STD_输入_句柄读取数据,并将读取的字节推送到套接字中。因为我想在退出时安全地关闭这个线程,所以我使用ReadFileEx()和重叠I/O,而不是普通的阻塞ReadFile()。其思想是,我的线程将在WaitForSingleObject()中等待,而不是在ReadFile()中,当主线程希望从线程离开时,它将在该对象上发出信号,从线程将唤醒并退出,然后主线程可以继续其关闭序列 我的问题是:尽管文档中说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
}
从描述可以传入的文件句柄类型的文档中:
此文件句柄必须已被删除
创建时文件\u标志\u重叠
标志,并且必须读取通用的
访问权
否则,ReadFileEx
将在您使用未使用重叠的FILE\u FLAG\u打开的句柄调用它时被阻止
您也可以调用WaitForSingleObject
或GetStdHandle
返回的句柄上的其他同步函数,并调用\u kbhit
或其他控制台事件处理组合,以确保有可用的输入。我担心是这样的。我不认为CONIN$技巧会达到我想要的效果,因为我不仅需要能够从键盘读取,还需要能够从父进程或文件重定向读取。。。