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