我有一个线程,我需要每隔10毫秒做一些事情.所以我有非常简单的代码,像那样:
while (work) {
// do something
Sleep(10000); // boost sleep can be also used
}
Run Code Online (Sandbox Code Playgroud)
我听说Sleep一般不推荐这样做,如果我用deadline_timer整体应用程序性能替代它会更好,特别是我会避免昂贵的"上下文切换".
我应该改变sleep,以deadline_timer若然有人可以举个例子?
Tan*_*ury 12
这一切都取决于10ms的要求.
如果应用程序需要在迭代之间延迟10ms,那么睡眠就可以了.假设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
可能值得考虑使用Boost.Thread来this_thread::sleep_for()实现可读性:
#include <boost/thread.hpp>
int main()
{
for (;;)
{
work();
boost::this_thread::sleep_for(boost::chrono::milliseconds(10));
}
}
Run Code Online (Sandbox Code Playgroud)
如果迭代之间的最大延迟是10ms,则执行工作所花费的时间需要从10ms延迟减少.假设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
在使用计时器同步教程可以是一个很好的起点.需要考虑的一点是Boost.Asio提供了一些定时器.如果10ms延迟不应受系统时钟变化的影响,那么考虑使用steady_timer.否则,deadline_timer应该没问题.
#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();
}
}
Run Code Online (Sandbox Code Playgroud)
另一个考虑因素是,如果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
如果完成所需的时间work()超过延迟,则work()不会每10ms完成一次.为此,可能需要使用多个线程.以下是一个时间轴,其中2个线程异步执行每10毫秒调度一次的工作,但需要13毫秒才能完成:
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 |
在使用定时器异步可提供的基本介绍.总体思路是将工作添加到其中io_service,并且每隔10毫秒运行一个正在运行的线程io_service将被调用work().可以根据完成所花费的时间量来增加或减少线程池大小work().在工作需要7毫秒的情况下,单个线程可以异步等待计时器.
#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();
}
Run Code Online (Sandbox Code Playgroud)
在引入并发以满足截止日期时,请验证是否work()是线程安全的.