为什么gui线程不应该在多线程公寓中生活?

时间:2014-09-06 17:05:56

标签: c++ windows multithreading com

COINIT - 用于指定Windows线程是在单个还是多线程单元中的枚举 - 文档(http://msdn.microsoft.com/en-gb/library/windows/desktop/ms678505(v=vs.85).aspx)声明:

  

多线程单元适用于非GUI线程。多线程公寓中的线程不应执行UI操作。这是因为UI线程需要消息泵,而COM不会为多线程单元中的线程提取消息。

为什么多线程公寓中的线程不应执行UI操作?在多线程单元中的线程中使用消息循环有什么问题? COM是否以某种方式为单线程单元中的线程提供了自动消息循环?

1 个答案:

答案 0 :(得分:5)

有点倒退,UI线程主要需要一个消息循环,以便它可以从Windows和其他进程接收通知。消息循环是producer-consumer problem的通用解决方案。随着操作系统和其他进程的产生,UI线程消耗。

UI线程使用大量非线程安全的代码。这包括在COM中实现的主要功能,如拖放,剪贴板,shell对话框,ActiveX控件,如浏览器。还有一大堆代码从未成为线程安全的,因为程序员不必这么做,写起来容易得多。这些功能需要一个STA线程,换句话说,一个线程通过将COINIT_APARTMENTTHREADED传递给CoInitializeEx()来初始化COM。

这是对COM的承诺,该线程将是一个好公民,不允许进行阻塞调用,必须抽取消息循环。它是消息循环,COM用于编组从工作线程到STA线程的调用,以保持COM对象的线程安全。当所有呼叫都来自同一个线程时,那么从来就不会出现安全问题。底层调用是SendMessage(),有大量的管道将函数参数从一个堆栈复制到另一个堆栈。 CoInitializeEx()创建一个由STA线程拥有的隐藏消息窗口,该窗口处理消息并实际进行调用。安全。