それはすべて、10ms の要件に依存します。
反復間の 10 ミリ秒の遅延
アプリケーションが反復間に 10 ミリ秒の遅延を必要とする場合は、スリープで問題ありません。work()
完了するまでに 7 ミリ秒かかると仮定すると、タイムラインは次のようになります。
時間 | アクション
-------+------------
0.000 秒 | 仕事を始める
0.007秒 | 仕事を終える、ブロックする
0.017秒 | ブロッキングを終了し、作業を開始します
0.024秒 | 仕事を終える、ブロックする
0.034 秒 | ブロッキングを終了し、作業を開始します
this_thread::sleep_for()
読みやすさのためにBoost.Thread の使用を検討する価値があるかもしれません。
#include <boost/thread.hpp>
int main()
{
for (;;)
{
work();
boost::this_thread::sleep_for(boost::chrono::milliseconds(10));
}
}
反復間の最大遅延は 10 ミリ秒
反復間の最大遅延が 10 ミリ秒の場合、作業の実行に費やす時間を 10 ミリ秒の遅延から減らす必要があります。work()
完了するまでに 7 ミリ秒かかると仮定すると、タイムラインは次のようになります。
時間 | アクション
-------+------------
0.000 秒 | 仕事を始める
0.007秒 | 仕事を終える、ブロックする
0.010 秒 | ブロッキングを終了し、作業を開始します
0.017秒 | 仕事を終える、ブロックする
0.020 秒 | ブロッキングを終了し、作業を開始します
タイマーを同期的に使用するチュートリアルは、開始するのに適した場所です。考慮すべき点の 1 つは、Boost.Asio がいくつかのタイマーを提供することです。10 ミリ秒の遅延がシステム クロックの変更による影響を受けない場合は、 の使用を検討して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();
}
}
もう 1 つの考慮事項は、work()
完了までに 13 ミリ秒かかる場合、最大遅延を超えているため、作業間に遅延がないことです。ただし、これは10 ミリ秒ごとwork()
ではなく、13 ミリ秒ごとに実行されることになりwork()
ます。
時間 | アクション
-------+------------
0.000 秒 | 仕事を始める
0.013 秒 | 仕事を終える、ブロックする
0.013 秒 | ブロッキングを終了し、作業を開始します
0.026秒 | 仕事を終える、ブロックする
0.039 秒 | ブロッキングを終了し、作業を開始します
10msごとに作業を行う
完了するのにかかる時間がwork()
遅延を超える場合、 work()
10ms ごとに実行されません。これを実現するには、複数のスレッドを使用する必要がある場合があります。以下は、10 ミリ秒ごとにスケジュールされた作業を非同期に実行する 2 つのスレッドのタイムラインですが、完了するまでに 13 ミリ秒かかります。
時間 | スレッド A | スレッド B
-------+----------------------------+------------- --------------
0.000 秒 | 仕事をスケジュールする、仕事を始める |
0.010 秒 | | | 仕事をスケジュールする、仕事を始める
0.013 秒 | 仕事を終えて、ブロック |
0.020 秒 | 仕事をスケジュールする、仕事を始める |
0.023 秒 | | | 仕事を終える、ブロックする
0.030 秒 | | | 仕事をスケジュールする、仕事を始める
0.033 秒 | 仕事を終えて、ブロック |
タイマーを非同期的に使用することで、基本的な導入が提供される場合があります。全体的な考え方は、 に作業を追加すること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()
がスレッドセーフであることを確認してください。