Windows 为什么另一个线程中阻塞的IO会阻止CreateWindowEx()返回
我有一个非常简单的Windows控制台应用程序,它首先创建一个线程来处理stdin上的输入。它使用Windows 为什么另一个线程中阻塞的IO会阻止CreateWindowEx()返回,windows,multithreading,winapi,io,nonblocking,Windows,Multithreading,Winapi,Io,Nonblocking,我有一个非常简单的Windows控制台应用程序,它首先创建一个线程来处理stdin上的输入。它使用main()中的CreateThread()来创建线程,线程做的第一件事是调用getchar()并阻塞,等待 然后main()使用RegisterClass()注册窗口类,并调用CreateWindowEx()创建一个不可见的消息窗口 但是CreateWindowEx()永远不会返回 如果我移除线程中的getchar(),并在(1)睡眠(1000)时将其替换为,一切正常 如果我添加Sleep(100
main()
中的CreateThread()
来创建线程,线程做的第一件事是调用getchar()
并阻塞,等待
然后main()
使用RegisterClass()
注册窗口类,并调用CreateWindowEx()
创建一个不可见的消息窗口
但是CreateWindowEx()
永远不会返回
如果我移除线程中的getchar()
,并在(1)睡眠(1000)时将其替换为代码>,一切正常
如果我添加Sleep(1000)
到线程函数的开始,调用CreateWindowEx()
成功,但线程中的I/O停止工作(getchar()
不返回)
为什么被阻止的第二个线程会干扰第一个线程?C运行时库不正式支持从由CreateThread
生成的线程调用。您应该使用CRT包装器函数,如\u beginthreadex
,这些函数在新线程上正确配置CRT线程本地状态
实际上,即使您违反了该规则,CRT也会竭尽全力使事情正常工作,但细节取决于您是静态链接还是动态链接CRT(因为这会影响是否有线程附加
回调)
通过仅对以\u beginthreadex
开头的线程进行CRT调用,尝试“正确”地执行此操作。(一种方法是继续使用CreateThread
,然后在工作线程中使用ReadConsole
而不是getchar
,另一种方法是使用\u beginthreadex
而不是CreateThread
)。窗口过程中发生了什么?您是否收到WM\u NC\u CREATE
?窗口过程只调用DefWindowProc(),除非它是WM\u用户消息,在这种情况下,它会将其记录到文件中。如果我不在线程中调用getchar(),这就行了。我不知道WM_NC_CREATE是否正在发送给它。你能提供吗?谢谢你的洞察力,本。我尝试快速地将线程代码更改为使用_beginthread(),但没有任何区别。它仍然挂在CreateWindowEx()中。我也尝试过让ReadConsole()工作,但这很有挑战性。我不知道为什么它现在还不起作用。我用_beginthreadex()无法让它起作用,但最终通过使用ReadFile()和WriteFile()替换所有stdio函数使它起作用。谢谢你,本@尼古拉斯:不客气。是的,ReadFile
是一个很好的I/O选择,包括控制台I/O,如果您只对字符数据感兴趣的话ReadConsole
提供字符数据(键盘和剪贴板)以及鼠标。