【发布时间】:2014-07-29 15:09:21
【问题描述】:
我正在用 C++ 开发一个 CORBA 服务器。由于各种原因(主要是因为我在主线程中还有其他任务要执行),我想使用非阻塞 API work_pending() 和 perform_work()。
简单的 sn-p 代码是:
while ( !shutdown )
{
if ( orb -> work_pending() )
orb -> perform_work();
if ( <other_requests> ) // my queue of non-corba activities
<process_request>;
}
但是,此代码以 100% 使用 CPU。
我猜 100% 的 CPU 利用率是不可接受的,即使在 [多核] 服务器中也不行(您能确认一下吗?),所以我对这个问题的解决方案是使用 sleep_until 改进 while 循环:
while ( !shutdown )
{
system_clock::time_point now = system_clock::now();
while ( orb -> work_pending() )
orb -> perform_work();
while ( <other_requests> )
<process_request>;
std::this_thread::sleep_until( now + milliseconds( 10 ) );
}
使用此解决方案,我可以确保 10 毫秒的最大响应时间和空闲时的低 CPU 负载。
当然我可以调整 10ms 的值来平衡这两个参数。
我的问题是:
- 这是一个有效的解决方案吗?
- 在我的情况下,是否有解决 100% CPU 问题的“标准”方法?
注意:我已经知道我可以使用阻塞 ORB::run() + 多线程,但我的问题是关于非阻塞 API ORB::perform_work(),所以请不要浪费时间问我为什么我想使用单线程架构,请不要提出ORB::perform_work() 的替代方案。我只是在尝试不同的架构。谢谢。
【问题讨论】:
-
如果你调用
yield()而不是睡眠,会发生什么? -
第二种设计有一个潜在的缺陷,如果
orb->work_pending()长时间没有变为false(例如因为工作复杂),那么在此期间其他请求将不会被处理。此外,在这种情况下,sleep_for比sleep_until更易于阅读。 -
@ElliottFrisch 不幸的是
yield()我得到了同样高的 CPU 负载。 -
看起来您采用的方法是使用所谓的轮询循环来轮询服务,以查看是否有工作要做。虽然肯定有轮询循环的应用程序,但它们往往具有一些不良特性,例如 100% CPU 利用率,除非使用像
sleep()或yield()这样的措施或其他措施来允许其他线程和进程访问 CPU。如果使用yield(),另一个建议是降低线程优先级。您可能还需要删除进程优先级。你真的应该使用阻塞或信号架构。 -
多线程有什么问题?
标签: c++ architecture cpu-usage corba