3

この簡単なテスト アプリケーションで、ブーストのdeadline_timerを使用してみましたが、問題が発生しました。expires_at()のメンバー関数を使用して、タイマーが 45 ミリ秒ごとにトリガーされるようにすることが目標ですdeadline_timer。(絶対時間が必要なので、考えていませんexpires_from_now()。ドリフトも今のところ気にしていません)。プログラムを実行すると、wait()45 ミリ秒待ちません! それでも、エラーは報告されません。どういうわけかライブラリを間違って使用していますか?

サンプルプログラム:

#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <iostream>
using namespace std;

int main()
{
        boost::asio::io_service Service;
        boost::shared_ptr<boost::thread> Thread;
        boost::asio::io_service::work RunForever(Service);
        Thread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&boost::asio::io_service::run, &Service)));
        boost::shared_ptr<boost::asio::deadline_timer> Timer(new boost::asio::deadline_timer(Service));

        while(1)
        {
                boost::posix_time::time_duration Duration;
                Duration = boost::posix_time::microseconds(45000);
                boost::posix_time::ptime Start = boost::posix_time::microsec_clock::local_time();
                boost::posix_time::ptime Deadline = Start + Duration;
                boost::system::error_code Error;
                size_t Result = Timer->expires_at(Deadline, Error);
                cout << Result << ' ' << Error << ' ';
                Timer->wait(Error);
                cout << Error << ' ';
                boost::posix_time::ptime End = boost::posix_time::microsec_clock::local_time();
                (cout << "Duration = " << (End - Start).total_milliseconds() << " milliseconds" << endl).flush();
        }
        return 0;
}
4

2 に答える 2

7

ローカル時刻とシステム時刻が混在しています。asio があなたの現地時間を比較している時間は、締め切りを設定したい時間から数時間後の可能性が高いので、すぐに戻ります (住んでいる場所によっては、この同じコードが数時間待つこともあります)。この混乱を避けるために、絶対時間は asio::time_traits から派生させる必要があります。

#include <boost/asio.hpp>
#include <boost/asio/time_traits.hpp>
#include <boost/thread.hpp> 
#include <boost/bind.hpp> 
#include <boost/date_time/posix_time/posix_time.hpp> 
#include <iostream> 
using namespace std;

typedef boost::asio::time_traits<boost::posix_time::ptime> time_traits_t;  
int main() {         
    boost::asio::io_service Service;         
    boost::shared_ptr<boost::thread> Thread;         
    boost::asio::io_service::work RunForever(Service);         
    Thread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&boost::asio::io_service::run, &Service)));
    boost::shared_ptr<boost::asio::deadline_timer> Timer(new boost::asio::deadline_timer(Service));          
    while(1)         
    {                 
        boost::posix_time::time_duration Duration;
        Duration = boost::posix_time::microseconds(45000);
        boost::posix_time::ptime Start = time_traits_t::now();
        boost::posix_time::ptime Deadline = Start + Duration;
        boost::system::error_code Error;
        size_t Result = Timer->expires_at(Deadline, Error);
        cout << Result << ' ' << Error << ' ';
        Timer->wait(Error);
        cout << Error << ' ';
        boost::posix_time::ptime End = boost::posix_time::microsec_clock::local_time();
        (cout << "Duration = " << (End - Start).total_milliseconds() << " milliseconds" << endl).flush();
     }         
    return 0; 
}

この場合、それはうまくいくはずです。

于 2011-03-22T01:48:13.250 に答える
4

io_service::run非同期メソッドと同期メソッドを混在させていますdeadline_timer::wait。これは機能しません。deadline_timer::async_waitと一緒に使用するか、 をio_service::runスキップしio_service::runて だけを使用してdeadline_timer::waitください。io_service:runまた、非同期ルートを使用する場合は、スレッドを呼び出す必要はありません。1 つのスレッドで十分です。どちらの概念も、 Asio チュートリアルの基本スキルのセクションで詳しく説明されています。

void print(const boost::system::error_code& /*e*/)
{
  std::cout << "Hello, world!\n";
}

int main()
{
  boost::asio::io_service io;

  boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
  t.async_wait(print);
  io.run();

  return 0;
}

io_serviceを呼び出す前に、サービスに何らかの作業を与える必要があることに注意してくださいrun()。この例でasync_waitは、その作業です。

無関係の可能性があります: 45ms は非常に小さなデルタです。私の経験では、ハンドラーが Asio epoll リアクター キューを通過する最短時間は約 30 ミリ秒であり、負荷が高くなると、これはかなり長くなる可能性があります。ただし、それはすべてアプリケーションに大きく依存します。

于 2011-03-22T00:46:34.113 に答える