在Windows中,即使没有待处理的输入,如何强制C的fread返回?

问题描述 投票:2回答:2

在具有两个线程的Windows程序中:thread1thread2

thread1在呼叫fread(buffer, 1, 10, stdin)等待输入时被阻止时,是否有可能从thread2做一些强迫fread返回?

到目前为止,我尝试从fclose(stdin)调用thread2,但它似乎不起作用。该程序卡在fclose调用,直到stdin流中有一些输入。

我想要实现的是优雅地终止thread1而不是仅仅用TerminateThread杀死它,因为thread1最后必须做一些工作。

另一件需要考虑的事情是stdin是命名管道的一端。我无法控制管道另一端的程序。 我需要的只是断开我的程序与管道的末端(在这种情况下为stdin)。

c winapi stdin eof fread
2个回答
5
投票

打电话给fclose(stdin)是一个非常糟糕的主意;它会导致未定义的行为,如果它发生在fread之前(它不是相对于它排序)或者如果调用fread的线程在stdin返回后对fread做任何其他事情,并且它不会解锁fread,因为fclose无法继续直到它获得锁定在stdin,正在进行中的fread被排除在外。

stdio从根本上说不适合你想做的事情。您可以通过第二个管道转发来修补它,另一个线程从stdin读取并写入您的新管道。然后你可以通过关闭它的写入结束来中止管道读取端的fread。额外的线程仍然会卡住,但是如果你要终止的话,这并不重要。或者(这可能更干净)您将使用文件描述符(或Windows文件句柄)而不是stdio和poll(或Windows等效)来确定是否有要读取的输入。您可以结合使用这些方法将特定于Windows的文件句柄逻辑放在额外的线程中(从而能够干净地终止它)并继续在程序逻辑线程中使用可移植的stdio


2
投票

如果你不能使用CancelSynchronousIo,你可以用CloseHandle关闭底层文件句柄,如下所示:

CloseHandle((HANDLE)_get_osfhandle(_fileno(stdin))) ;

这应该导致fread返回。

© www.soinside.com 2019 - 2024. All rights reserved.