Я пытаюсь смоделировать проблему «Обедающих философов», но у меня возникают проблемы с ее визуализацией. Когда поток переходит от Waiting () к Eating () к Thinking (), он изменяет переменную с именем state, чтобы представить это. Однако в моем основном потоке он никогда не видит изменения переменной состояния. Он вызывает функцию возврата для состояния при рисовании, чтобы изменить цвет философа.
Любая помощь с этим?
Вот некоторый код:
Изменение состояния
void Philosopher::Eat()
{
state_ = EATING;
Sleep(500);
}
Функция возврата
Philosopher::_state Philosopher::ReturnState()
{
return state_;
}
Вызов функции возврата
Philosopher::_state current_state_;
current_state_ = philosopher_[i].ReturnState();
switch (current_state_)
{
case Philosopher::PICKING:
{
glColor3f(1, 0, 0);
break;
}
case Philosopher::EATING:
{
glColor3f(0, 1, 0);
break;
}
case Philosopher::THINKING:
{
glColor3f(0, 0, 1);
break;
}
}
Без синхронизации попытки доступа к одной переменной из нескольких потоков являются неопределенным поведением. Добавьте мьютекс.
Поскольку это единственный вопрос, который я смог найти:
Любая помощь с этим?
И этому вопросу уже 6 месяцев, я подумал, что просто покажу, как это сделать. На самом деле здесь есть четыре способы сделать это (в C ++):
Обеденные Философы перезагрузились
Простой ответ — создать массив std::mutex
который представляет собой разветвление между каждым философом и заблокировать их (для еды), используя std::lock
, что-то вроде этого:
std::unique_lock<std::mutex> left (mutexes[i], std::defer_lock);
std::unique_lock<std::mutex> right(mutexes[j], std::defer_lock);
std::lock(left, right);
Если вы сделаете это и обнаружите, что ваш код тратит значительное количество времени на вращение, напишите отчет об ошибке вашему поставщику std :: lib и укажите на этот документ. Они узнают это.
Или, если вы предпочитаете, просто скопируйте один из четырех ::lock
реализации из бумаги (в зависимости от того, что лучше для вас) и использовать его.