gpt4 book ai didi

c++ - pthread_cond_wait 奇怪的行为

转载 作者:行者123 更新时间:2023-11-28 07:45:16 26 4
gpt4 key购买 nike

我正在尝试解决 Dining philosophers problem使用 C++。

代码是用 g++ -lpthread 编译的。

整个解决方案在 philosophers github 上.存储库包含两个 cpp 文件:main.cpp 和 philosopher.cpp。 “Main.cpp”创建互斥变量、信号量、5 个条件变量、5 个 fork ,并启动哲学家。信号量仅用于同步哲学家的开始。其他参数被传递给哲学家以解决问题。 “Philosopher.cpp”包含给定问题的解决方案,但在几步之后发生死锁。

当哲学家 0 正在吃饭,而哲学家 1(在他旁边)想要拿 fork 时,就会发生死锁。然后,哲学家 1 拿走了互斥量,并且在哲学家 0 放下他的 fork 之前不会归还它。哲学家 0 不能放下他的 fork ,因为互斥锁被拿走了,所以我们陷入了僵局。问题出在 Philosopher::take_fork 方法中,对 pthread_cond_wait(a,b) 的调用未释放互斥体 b。不明白为什么?

// Taking fork. If eather lef or right fork is taken, wait.
void Philosopher::take_fork(){
pthread_mutex_lock(&mon);
std::cout << "Philosopher " << id << " is waiting on forks" << std::endl;
while(!fork[id] || !fork[(id + 1)%N])
pthread_cond_wait(cond + id, &mon);
fork[id] = fork[(id + 1)%N] = false;
std::cout << "Philosopher " << id << " is eating" << std::endl;
pthread_mutex_unlock(&mon);
}

请引用this code剩下的。

最佳答案

您对 pthread_cond_wait() 的调用没有问题,所以问题一定出在其他地方。我可以看到你有三个错误:

首先,在main() 中,您只初始化数组中的第一个 条件变量。您需要初始化所有 N 个条件变量:

for(int i = 0; i < N; i++) {
fork[i] = true;
pthread_cond_init(&cond[i], NULL);
}

pthread_mutex_init(&mon, NULL);

其次,在 put_fork() 中,您对要发出信号的条件变量之一的计算不正确:

pthread_cond_signal(cond + (id-1)%N);    /* incorrect */

id 等于 0 时,(id - 1) % N 等于 -1,因此这将尝试向 cond - 1< 发出信号,它不指向条件变量(这个指针实际上可能会破坏你的互斥锁,因为它很可能直接放在堆栈上的 cond 之前)。你真正想要的计算是:

pthread_cond_signal(cond + (id + N - 1) % N);

第三个错误不是导致死锁的原因,但您不应该在每次调用 rand() 时都调用 srand(time(NULL)) -只需调用一次,在 main() 的开头。

关于c++ - pthread_cond_wait 奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15024339/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com