У меня есть ситуация, когда notify () может быть вызван перед wait ().
Я пытаюсь создать симулятор для планирования следующего события, когда я «уведомляю» его, отправляя ему сообщения. Поэтому я разработал цепочку ожидания-> уведомления-> расписания
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();
}
}
проблема здесь в том, что: могут быть ситуации, когда notify () вызывается перед вызовом wait ().
Есть ли выход для такой ситуации?
благодарю вас
Переменные условия вряд ли могут использоваться отдельно, хотя бы потому, что, как вы заметили, они пробуждают только ожидающие в настоящий момент потоки. Существует также проблема ложных пробуждений (т. Е. Переменная условия может иногда пробуждать поток без какого-либо соответствующего 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();
Я думаю, что ответ syam в целом хорош, но в вашем конкретном случае, когда вы, похоже, используете ns-3, я бы предложил вместо этого реструктурировать свой код для использования правильных примитивов в ns-3:
Имейте в виду, что API ns-3 не потокобезопасен в целом. Единственный API ns-3, который является потокобезопасным, это ns3 :: Simulator :: ScheduleWithContext. Я не могу подчеркнуть, насколько важно не использовать любой другой API, доступный в пространстве имен ns-3 :: из потока, который не является основным потоком.