23

wait() の前に notify() を「呼び出すことができる」状況があります。

メッセージを送信して彼に「通知」するときに、次のイベントをスケジュールするシミュレーターを作成しようとしています。そこで、wait->notify->scedule チェーンを考案しました

void Broker::pause()
{
    boost::unique_lock<boost::mutex> lock(m_pause_mutex);
    {
        std::cout << "pausing the simulation" << std::endl;
        m_cond_cnn.wait(lock);
        std::cout << "Simulation UNpaused" << std::endl;
        // the following line causes the current function to be called at 
        // a later time, and a notify() can happen before the current function
        // is called again
        Simulator::Schedule(MilliSeconds(xxx), &Broker::pause, this);
    }
}

void Broker::messageReceiveCallback(std::string message) {
    boost::unique_lock<boost::mutex> lock(m_pause_mutex);
    {
        m_cond_cnn.notify_one();
    }
}

ここでの問題は、wait() が呼び出される前に notify() が呼び出される場合があることです。

このような状況の解決策はありますか?ありがとうございました

4

2 に答える 2

21

お気づきのように、条件変数は現在待機中のスレッドを起こすだけなので、条件変数を単独で使用することはほとんどありません。偽のウェイクアップの問題もあります (つまり、条件変数は、対応するnotifyものが呼び出されていないスレッドをウェイクアップすることがあります)。通常、条件変数が適切に機能するには、より信頼性の高い状態を維持するために別の変数が必要です。

これらの両方の問題を解決するには、あなたの場合、ブール値のフラグを追加するだけです:

boost::unique_lock<boost::mutex> lock(m_pause_mutex);
while (!someFlag)
    m_cond_cnn.wait(lock);
someFlag = false;

//...

boost::unique_lock<boost::mutex> lock(m_pause_mutex);
someFlag = true;
m_cond_cnn.notify_one();
于 2013-07-10T05:36:56.743 に答える
3

syamの答えは一般的には問題ないと思いますが、ns-3を使用しているように見える特定のケースでは、代わりにns-3で正しいプリミティブを使用するようにコードを再構築することをお勧めします:

  1. ns-3 リアルタイム シミュレータの実装のいずれかを使用していると思われます。良い。
  2. 0.1 秒間の keeplive イベントをスケジュールして、シミュレーターが実行され続けることを確認します (イベントが残っていない場合、実行が開始されます)。
  3. 必要に応じて、このキープアライブ イベントでブール値を使用して、キープアライブ イベントのスケジュールを変更するか、Simulator::Stop を呼び出す必要があるかどうかを確認します。
  4. Simulator::Run() でシミュレーターのメインループを実行するスレッドを作成します。シミュレーターは、次にスケジュールされたイベントの有効期限が切れるまで、または新しいイベントが外部でスケジュールされるまでスリープします。
  5. Simulator::ScheduleWithContext を使用して、別のスレッドから外部でイベントをスケジュールします。

一般に、ns-3 API はスレッドセーフではないことに注意してください。スレッドセーフな ns-3 API は ns3::Simulator::ScheduleWithContext だけです。メイン スレッドではないスレッドから ns-3:: 名前空間で利用可能な他の API使用しないことがいかに重要であるかを強調することはできません。

于 2013-07-15T08:01:23.350 に答える