【发布时间】:2011-04-18 09:12:55
【问题描述】:
过去几天我一直在尝试为一个应用程序找到一个好的架构,经过一些研究我终于卡住了,原因是 COM。
相关应用将有多个 GUI 线程,它们会为工作线程安排工作项。工作线程将通过 CoInitialize(NULL); 初始化 COM,创建一些 COM 组件并将进入一个循环,该循环将等待 WaitForMultipleObjects(2, ...) (ExitEvent - 表示应用程序正在关闭,ManualResetEvent - 表示实际上有工作项要处理),并且在成功等待时,将处理这些项并将它们 PostMessage 回 GUI 线程。如果队列为空,ManualResetEvent 将在 worker 内部重置,并将发生在队列临界区中。
问题是 COM 像往常一样让一切变得困难 1000 倍...
如果我理解正确的话,CoInitialize(NULL);创建一个隐藏窗口,在 WaitForSingle/MultipleObject/s 期间发布的任何消息都可能导致死锁。
所以,我需要调用 MsgWaitForMultiple 对象。如果消息未正确发送,则反过来可能会失败。不幸的是,我不太明白如何以正确的方式泵送它们。我必须创建自己的消息循环吗?如果 COM 决定创建消息框,应用会崩溃吗?
到目前为止,我似乎必须这样进行?
HANDLE hEvents[2] = {};
int ThreadProc(LPVOID lpParam) {
int nRetVal = 0;
CoInitialize(NULL);
CComPtr<ISomething> smthn;
smthn.CoCreateInstance(...);
MSG msg = {};
bool bRun = true;
while(bRun) {
while(PeekMessage(&msg, ??NULL/-1??, 0, 0, PM_REMOVE)) { /*Which one here?*/
if(msg.Message == WM_QUIT) {
bRun = false;
nRetVal = msg.wParam;
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(MsgWaitForMultipleObjects(2, &hEvents, ...)) {
if(exitevent) { bRun = false; nRetVal = 0; }
else if(processevent) { [processdata] }
}
}
smthn.release();
CoUninitialize();
return nRetVal;
}
但是隐藏窗口、消息框呢,我是不是走对了路?
【问题讨论】:
-
COM 对象是否在线程之间移动?还是他们在一个线程中死了?简而言之,COM 对象做了什么?我认为你的架构很遥远,因为你在 SO 上得到了一些不好的建议。
-
我不明白这个问题。这里的实际问题是什么?
-
另外,请解释“多个 GUI 线程”。你只是指隐藏的 COM 窗口,还是真的想拥有多个主 GUI 线程?
-
@Hans:查看 Madman 过去几天的帖子,了解这篇帖子的来源。
-
COM 对象在线程内生死存亡。 MSXML 就是其中之一,但还有其他一些我无法控制。不能保证它们是 COINIT_MULTITHREADED 安全的。
标签: c++ multithreading winapi com synchronization