我有一个线程,我需要做的事情每隔10毫秒。 所以,我有非常简单的代码,这样的:
while (work) {
// do something
Sleep(10000); // boost sleep can be also used
}
听说Sleep
中一般不建议,如果我用它替换deadline_timer
整体应用性能会更好,尤其是我将避免昂贵的“上下文切换”。
我应该改变sleep
到deadline_timer
若然有人可以举个例子?
我有一个线程,我需要做的事情每隔10毫秒。 所以,我有非常简单的代码,这样的:
while (work) {
// do something
Sleep(10000); // boost sleep can be also used
}
听说Sleep
中一般不建议,如果我用它替换deadline_timer
整体应用性能会更好,尤其是我将避免昂贵的“上下文切换”。
我应该改变sleep
到deadline_timer
若然有人可以举个例子?
这一切都取决于为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));
}
}
如果迭代之间的最大延迟为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();
}
}
另一个考虑是,如果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();
}
当引入并发,以满足最后期限,验证work()
是线程安全的。
使用Sleep()
就可以了。 我想这是Windows的API函数,它无论如何需要毫秒,所以你可能要经过10而不是10000,如果你想10毫秒。
在使用睡眠这样一个简单的程序,最大的问题可能会漂移。 如果间隔必须相当精确,你会面临一些挑战。 你没有说你是否在意,如果你的实际逻辑需要几毫秒的时间即可完成会发生什么 - 你可以10毫秒后开始下一个迭代,以下为“追赶”。