在具有两个线程的Windows程序中:thread1
和thread2
。
当thread1
在呼叫fread(buffer, 1, 10, stdin)
等待输入时被阻止时,是否有可能从thread2
做一些强迫fread
返回?
到目前为止,我尝试从fclose(stdin)
调用thread2
,但它似乎不起作用。该程序卡在fclose
调用,直到stdin
流中有一些输入。
我想要实现的是优雅地终止thread1
而不是仅仅用TerminateThread
杀死它,因为thread1
最后必须做一些工作。
另一件需要考虑的事情是stdin
是命名管道的一端。我无法控制管道另一端的程序。
我需要的只是断开我的程序与管道的末端(在这种情况下为stdin
)。
打电话给fclose(stdin)
是一个非常糟糕的主意;它会导致未定义的行为,如果它发生在fread
之前(它不是相对于它排序)或者如果调用fread
的线程在stdin
返回后对fread
做任何其他事情,并且它不会解锁fread
,因为fclose
无法继续直到它获得锁定在stdin
,正在进行中的fread
被排除在外。
stdio
从根本上说不适合你想做的事情。您可以通过第二个管道转发来修补它,另一个线程从stdin
读取并写入您的新管道。然后你可以通过关闭它的写入结束来中止管道读取端的fread
。额外的线程仍然会卡住,但是如果你要终止的话,这并不重要。或者(这可能更干净)您将使用文件描述符(或Windows文件句柄)而不是stdio和poll
(或Windows等效)来确定是否有要读取的输入。您可以结合使用这些方法将特定于Windows的文件句柄逻辑放在额外的线程中(从而能够干净地终止它)并继续在程序逻辑线程中使用可移植的stdio
。
如果你不能使用CancelSynchronousIo
,你可以用CloseHandle
关闭底层文件句柄,如下所示:
CloseHandle((HANDLE)_get_osfhandle(_fileno(stdin))) ;
这应该导致fread
返回。