0

ブースト asio タイマーとセーフ スレッドの動作について質問があります。たとえば、次のクラスがあるとします。

CTest.h:

class CTest
{
    boost::asio::io_service io;
    boost::asio::deadline_timer timer;

    void Check();
    CTest ();

    ~CTest ();
};

そして CTest.cpp:

CTest::CTest():
timer (io, boost::posix_time::seconds(0))
{
    timer.async_wait(boost::bind(&CTest::Check, this));
    boost::thread t(boost::bind(&boost::asio::io_service::run, &io));
}

void CTest::Check()
{
    //some work

    m_timer.expires_from_now(boost::posix_time::seconds(10));
    m_timer.async_wait(boost::bind(&CTest::Check, this));

}

CTest::~CTest()
{
     io.stop();
}

では、問題は、スレッド セーフの確認をどのように終了するかです。つまり、この Check 関数はデストラクタの後に呼び出すことができ、クラッシュが発生します。

4

2 に答える 2

2

io_service::stop() を使用することは、ほとんどありません。

いくつかのポイント:

  • スレッド オブジェクトを保持し、thread.join() を呼び出して、完全であることを確認します。
  • io.stop() を呼び出さず、m_timer.cancel() を呼び出してから m_thread.join() を呼び出してクリーンアップします。
  • オブジェクトの有効期間をよりきれいに管理するには、shared_ptr と weak_ptr を使用することを検討してください (つまり、weak_ptr インスタンスを async_wait コールバックではなく、bare にバインドしますthis。コールバック関数で、weak_ptr を shared_ptr に変換し、それが有効な場合はメソッドを呼び出します。
  • m_timer は複数のスレッドから使​​用されるため、mutex を使用してアクセスを管理する必要があります。

ほんの数点。コードを書き直すつもりはありません。

于 2013-03-25T11:43:36.247 に答える
1

デストラクタはすべてのタイマーを停止する必要があるため、オブジェクトが破棄された後に呼び出されることはありません: m_timer.cancel(). また、同じオブジェクトに対するメソッドの同時呼び出しを防ぎたい場合は、boost::bindboost::asio::strand::wrapでラップします。例については、asio のドキュメントを参照してください。

于 2013-03-25T13:08:17.807 に答える