我应该如何使用条件变量解决 Dining Philosophers 问题中的饥饿问题?
How should I solve starving in Dinning Philosophers problem using conditional variables?
我用 condition_variables 写了一个简单的模拟哲学家吃饭的程序,问题是有些哲学家从来没有机会吃饭。
我尝试在 _condVar.Wait lambda 函数中放置断点以确保 putdownForks 方法通知其他等待线程,我这样做了,但我仍然不明白为什么其他线程永远无法吃东西。
#include <condition_variable>
#include <iostream>
#include <thread>
#include <unistd.h>
#define thread_num 5
#define HUNGRY 0
#define EATING 1
#define THINKING 2
using namespace std;
thread _threads[thread_num];
mutex _mutex;
condition_variable _condVar;
int _states[thread_num];
bool _isCancelRequested;
void think(int id){
usleep(rand() % 1000000 + 2000000);
}
void eat(int id){
usleep(rand() % 1000000 + 2000000);
}
void putdownForks(int id){
{
unique_lock<mutex> lck(_mutex);
_states[id] = THINKING;
}
_condVar.notify_all();
}
void pickupForks(int id){
int leftNeighbourId = (id -1 )%thread_num;
if(leftNeighbourId<0)leftNeighbourId+=thread_num;
int rightNeighbourId= (id+1)%thread_num;
{
unique_lock<mutex> lck(_mutex);
_states[id] = HUNGRY;
bool isLeftNeighbourEating = _states[leftNeighbourId] == EATING;
bool isRightNeighbourEating = _states[rightNeighbourId] == EATING;
_condVar.wait(lck,
[isLeftNeighbourEating, isRightNeighbourEating]
{
return !(isLeftNeighbourEating || isRightNeighbourEating);
});
_states[id] = EATING;
}
}
void philosopher(int id){
while(!_isCancelRequested){
think(id);
pickupForks(id);
eat(id);
putdownForks(id);
}
}
void print_info()
{
{
unique_lock<mutex> lck(_mutex);
for(int i=0;i<thread_num;i++)
{
cout << "Id: "<< i<< " State: "<< _states[i]<<endl;
}
cout << endl;
}
}
void info(){
while (!_isCancelRequested)
{
usleep(1000000);
print_info();
}
}
int main(){
for(int i=0; i<thread_num;i++){
_threads[i]= thread(philosopher,i);
}
thread info_thread(info);
for(int i=0; i<thread_num;i++){
_threads[i].join();
}
info_thread.join();
}
这是状态随时间变化的输出
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
如您所见,id 为 1、2 和 4 的哲学家从不进食。
哇,Whosebug-effect这次真难受。
通知后,等待中的条件需要重新评估,所以每次 conditional_variable 通知时我需要 "renew" 邻居的状态。 pickupForks 方法应如下所示:
void pickupForks(int id){
int leftNeighbourId = (id -1 )%thread_num;
if(leftNeighbourId<0)leftNeighbourId+=thread_num;
int rightNeighbourId= (id+1)%thread_num;
{
unique_lock<mutex> lck(_mutex);
_states[id] = HUNGRY;
_condVar.wait(lck,
[leftNeighbourId, rightNeighbourId]
{
bool isLeftNeighbourEating = _states[leftNeighbourId] == EATING;
bool isRightNeighbourEating = _states[rightNeighbourId] == EATING;
return !(isLeftNeighbourEating || isRightNeighbourEating);
});
_states[id] = EATING;
}
}
我用 condition_variables 写了一个简单的模拟哲学家吃饭的程序,问题是有些哲学家从来没有机会吃饭。
我尝试在 _condVar.Wait lambda 函数中放置断点以确保 putdownForks 方法通知其他等待线程,我这样做了,但我仍然不明白为什么其他线程永远无法吃东西。
#include <condition_variable>
#include <iostream>
#include <thread>
#include <unistd.h>
#define thread_num 5
#define HUNGRY 0
#define EATING 1
#define THINKING 2
using namespace std;
thread _threads[thread_num];
mutex _mutex;
condition_variable _condVar;
int _states[thread_num];
bool _isCancelRequested;
void think(int id){
usleep(rand() % 1000000 + 2000000);
}
void eat(int id){
usleep(rand() % 1000000 + 2000000);
}
void putdownForks(int id){
{
unique_lock<mutex> lck(_mutex);
_states[id] = THINKING;
}
_condVar.notify_all();
}
void pickupForks(int id){
int leftNeighbourId = (id -1 )%thread_num;
if(leftNeighbourId<0)leftNeighbourId+=thread_num;
int rightNeighbourId= (id+1)%thread_num;
{
unique_lock<mutex> lck(_mutex);
_states[id] = HUNGRY;
bool isLeftNeighbourEating = _states[leftNeighbourId] == EATING;
bool isRightNeighbourEating = _states[rightNeighbourId] == EATING;
_condVar.wait(lck,
[isLeftNeighbourEating, isRightNeighbourEating]
{
return !(isLeftNeighbourEating || isRightNeighbourEating);
});
_states[id] = EATING;
}
}
void philosopher(int id){
while(!_isCancelRequested){
think(id);
pickupForks(id);
eat(id);
putdownForks(id);
}
}
void print_info()
{
{
unique_lock<mutex> lck(_mutex);
for(int i=0;i<thread_num;i++)
{
cout << "Id: "<< i<< " State: "<< _states[i]<<endl;
}
cout << endl;
}
}
void info(){
while (!_isCancelRequested)
{
usleep(1000000);
print_info();
}
}
int main(){
for(int i=0; i<thread_num;i++){
_threads[i]= thread(philosopher,i);
}
thread info_thread(info);
for(int i=0; i<thread_num;i++){
_threads[i].join();
}
info_thread.join();
}
这是状态随时间变化的输出
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 1
Id: 4 State: 0
Id: 0 State: 1
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
Id: 0 State: 2
Id: 1 State: 0
Id: 2 State: 0
Id: 3 State: 2
Id: 4 State: 0
如您所见,id 为 1、2 和 4 的哲学家从不进食。
哇,Whosebug-effect这次真难受。 通知后,等待中的条件需要重新评估,所以每次 conditional_variable 通知时我需要 "renew" 邻居的状态。 pickupForks 方法应如下所示:
void pickupForks(int id){
int leftNeighbourId = (id -1 )%thread_num;
if(leftNeighbourId<0)leftNeighbourId+=thread_num;
int rightNeighbourId= (id+1)%thread_num;
{
unique_lock<mutex> lck(_mutex);
_states[id] = HUNGRY;
_condVar.wait(lck,
[leftNeighbourId, rightNeighbourId]
{
bool isLeftNeighbourEating = _states[leftNeighbourId] == EATING;
bool isRightNeighbourEating = _states[rightNeighbourId] == EATING;
return !(isLeftNeighbourEating || isRightNeighbourEating);
});
_states[id] = EATING;
}
}