我有一个性能问题,客户端在我的C++应用程序的DOM中创建了数百种特定类型的对象"Foo“。每个Foo实例都有自己的异步工作队列和自己的线程。显然,这不是可伸缩的。
我需要在工作队列中共享线程,并且我不想重复发明轮子。我需要支持XP,所以我不能使用Vista/Win7线程池。处理每个队列项所需完成的工作涉及在多线程COM单元中进行COM调用。XP线程池的文档表明,可以在线程工作者函数回调中使用MTA单元调用CoInitializeEx()。我已经写了一个测试应用程序,并验证了这是可行的。我让应用程序在WorkItem回调函数中使用和不使用CoInitializeEx/CoUninitialize对的情况下运行100万次迭代。使用CoInit*调用需要35秒,没有调用需要5秒。这对我的应用程序来说开销太大了。由于线程池是每个进程的,并且第三方代码在我的进程中运行,所以我假设每个线程只使用一次CoInitializeEx()而从不使用CoUninitialize()是不安全的。
考虑到所有这些,有什么方法可以使用Win32线程池吗?是我错过了什么,还是XP线程池对于高性能COM应用程序非常无用?我是不是必须创建自己的线程共享系统?
发布于 2010-02-04 22:31:39
你有没有核实是什么花了这么长时间?例如,它是对CoInitializeEx()的调用吗?您绝对不需要在每个任务中调用一次CoInitialize。你也不要说你产生了多少线程,例如,如果你在双核上运行,你的工作是CPU密集型的,不要期望超过2倍的加速,如果你的工作不是CPU密集型的,那么它会等待一些资源(内存,磁盘,网络),加速将同样受到限制,如果有一个锁被持有,可能会变得更糟。
如果你可以使用Visual Studio2010,看看Parallel Pattern Library和Asynchronous Agents Library,有几个工具可以帮助你减少编写代码。
如果不能,至少可以尝试在TLS中放置一个表示COM是否已在该线程上初始化的令牌,并在不需要时使用该令牌绕过对CoInitialize的调用。
发布于 2010-02-04 09:37:38
我假设每个线程只使用一次CoInitializeEx()而不使用CoUninitialize()是不安全的。
如果线程在没有调用CoUninitialize的情况下退出,Windows将进行清理,我们知道这是可行的,因为如果不这样做,当线程崩溃或中止时将不会进行清理。
因此,这种黑客攻击可能导致问题的唯一方式是,有人试图将需要STA公寓的工作项目排队,这似乎不太可能。
我会忍不住去尝试的。
https://stackoverflow.com/questions/2196725
复制相似问题