c++ - boost deadline_timer 最小示例 : should I substitute "sleep"?

标签 c++ boost

我有一个线程,我需要每 10 毫秒执行一次操作。所以我有非常简单的代码,就像这样:

while (work) {
    // do something
    Sleep(10000); // boost sleep can be also used
}

我听说一般不推荐使用 Sleep,如果我用 deadline_timer 代替它,整体应用程序性能会更好,特别是我会避免昂贵的“上下文切换” .

我应该将 sleep 更改为 deadline_timer 如果可以,有人可以举个例子吗?

最佳答案

这一切都取决于对 10ms 的要求。


迭代之间延迟 10 毫秒

如果应用程序需要在迭代之间有 10 毫秒的延迟,那么 sleep 就可以了。假设 work() 需要 7 毫秒才能完成,时间轴将产生以下结果:

 Time  | Action
-------+------------
0.000s | begin work
0.007s | finish work, block
0.017s | finish blocking, begin work
0.024s | finish work, block
0.034s | finish blocking, begin work

It may be worth considering using Boost.Thread's this_thread::sleep_for() for readability:

#include <boost/thread.hpp>

int main()
{
  for (;;)
  {
    work();
    boost::this_thread::sleep_for(boost::chrono::milliseconds(10));
  }
}

迭代之间的最大延迟为 10 毫秒

如果迭代之间的最大延迟为 10 毫秒,则执行工作所花费的时间需要从 10 毫秒延迟减少。假设 work() 需要 7 毫秒才能完成,时间轴将产生以下结果:

 Time  | Action
-------+------------
0.000s | begin work
0.007s | finish work, block
0.010s | finish blocking, begin work
0.017s | finish work, block
0.020s | finish blocking, begin work

The using a timer synchronously tutorial can be a good place to start. One point to consider is that Boost.Asio provides a few timers. If the 10ms delays should not be affected by changes to the system clock, then a consider using steady_timer. Otherwise, deadline_timer should be fine.

#include <boost/asio/steady_timer.hpp>

boost::asio::io_service io_service;
boost::asio::steady_timer timer(io_service);

int main()
{
  for (;;)
  {
    timer.expires_from_now(boost::chrono::milliseconds(10));
    work();
    timer.wait();
  }
}

另一个考虑因素是,如果 work() 需要 13 毫秒才能完成,那么工作之间将不会有延迟,因为已经超过了最大延迟。但是,这会导致 work() 每 13 毫秒执行一次,而不是 work() 每 10 毫秒执行一次。

 Time  | Action
-------+------------
0.000s | begin work
0.013s | finish work, block
0.013s | finish blocking, begin work
0.026s | finish work, block
0.039s | finish blocking, begin work

Perform work every 10ms

If the time it takes to complete work() exceeds the delay, then work() will not be done every 10ms. To accomplish this, multiple threads may need to be used. The following is a timeline with 2 threads asynchronously performing work that is scheduled every 10 milliseconds, but takes 13 milliseconds to complete:

 Time  | Thread A                   | Thread B
-------+----------------------------+---------------------------
0.000s | schedule work, begin work  |
0.010s |                            | schedule work, begin work 
0.013s | finish work, block         |
0.020s | schedule work, begin work  |
0.023s |                            | finish work, block
0.030s |                            | schedule work, begin work
0.033s | finish work, block         |

The using a timer asynchronously may provide a basic introduction. The overall idea is to add work into the io_service, and every 10 milliseconds a thread that is running the io_service will be selected to invoke work(). The thread pool size can be increased or decreased based on the amount of time work() takes to complete. In the case where work takes 7 milliseconds, then a single thread could asynchronously wait on the timer.

#include <boost/asio/steady_timer.hpp>

boost::asio::io_service io_service;
boost::asio::steady_timer timer(io_service);

void handle_timer(const boost::system::error_code& error);

void schedule_work()
{
  // Schedule more work.
  timer.expires_from_now(boost::chrono::milliseconds(10));
  timer.async_wait(&handle_timer);
}

void handle_timer(const boost::system::error_code& error)
{
  if (error) return;
  schedule_work();
  work();
}

int main()
{
  // Add work to io_service.
  schedule_work();

  // Create 2 threads that will run io_service.
  boost::thread_group threads;
  for (std::size_t i = 0; i < 2; ++i)
    threads.create_thread(boost::bind(
      &boost::asio::io_service::run, &io_service));

  // Wait for threads to finish.
  threads.join_all();
}

在引入并发以满足截止日期时,验证work() 是线程安全的。

关于c++ - boost deadline_timer 最小示例 : should I substitute "sleep"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16354727/

相关文章:

c++ - 聚焦时为 QSpinBox 设置边框

C++ 流重定向

c++ - 使用 GCC 4.7 从初始化程序列表初始化 unique_ptrs 的容器失败

c++ - 用 C++ 思考?

c++ - 如何按值对 **boost::unordered_map** 进行排序并按该顺序仅返回键?

c++ - 如何动态转换 boost::scoped_ptr?

c++ - Seek 不适用于使用 boost filtering_istreambuf 初始化的 std::istream

c++ - 赋值开关大小写 c++

c++ - 使用 boost 查找数据集的峰度

c++ - 在嵌套的 boost 绑定(bind)中使用模板函数