为什么在另一个线程中阻塞的IO阻止CreateWindowEx()返回
我有一个非常简单的Windows控制台应用程序,它首先创建一个线程来处理stdin上的输入。它使用CreateThread()
中的main()
来创建线程,线程所做的第一件事情是调用getchar()
并阻止,等待。为什么在另一个线程中阻塞的IO阻止CreateWindowEx()返回
然后main()
使用RegisterClass()
注册一个窗口类并调用CreateWindowEx()
来创建一个不可见的消息窗口。
但是CreateWindowEx()
永不退货。
如果我删除线程中的getchar()
并将其替换为while (1) Sleep(1000);
,则一切正常。
如果我将Sleep(1000);
添加到线程函数的开头,CreateWindowEx()
调用成功,但线程中的I/O停止工作(getchar()
不返回)。
为什么被阻塞的第二个线程会干扰第一个线程?
C运行时库不正式支持从CreateThread
生成的线程调用。您应该使用CRT包装功能,例如_beginthreadex
,它可以在新线程上正确配置CRT线程本地状态。
实际上,即使违反了规则,CRT也会竭尽全力让其工作,但细节取决于您是否静态或动态地与CRT连接(因为这会影响是否存在回调THREAD_ATTACH
) 。
尝试通过仅在_beginthreadex
开始的线程上进行CRT调用来做到“正确”。 (一种方法是继续使用CreateThread
,然后在工作线程中使用ReadConsole
而不是getchar
,另一种方法是使用_beginthreadex
而不是CreateThread
)。
谢谢你的见解,本。我试着快速改变线程代码来使用_beginthread(),但它没有什么区别。它仍然挂在CreateWindowEx()中。我还修改了ReadConsole()来代替工作,但事实证明这很具有挑战性。我不确定它为什么还没有工作。 – Nicholas
我无法使用_beginthreadex()获得此工作,但最终能够通过使用ReadFile()和WriteFile()来替换所有stdio函数来使其工作。谢谢Ben! – Nicholas
@尼古拉斯:不客气。是的,如果你只对字符数据感兴趣,'ReadFile'对I/O来说是一个不错的选择,包括控制台I/O。 'ReadConsole'提供字符数据(键盘和剪贴板)以及鼠标。 –
你的窗口过程发生了什么?你收到了“WM_NC_CREATE”吗? –
窗口过程只是调用DefWindowProc(),除非它是WM_USER消息,在这种情况下,它会将该消息记录到文件中。如果我不在线程中调用getchar(),这将起作用。我不知道WM_NC_CREATE是否正在发送给它。 – Nicholas
你能提供[一个MCVE](http://stackoverflow.com/help/mcve)吗? –