Windows 为什么另一个线程中阻塞的IO会阻止CreateWindowEx()返回

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

我有一个非常简单的Windows控制台应用程序,它首先创建一个线程来处理stdin上的输入。它使用
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
提供字符数据(键盘和剪贴板)以及鼠标。