我正在尝试使用资源层次结构解决方案在C中实现Dining Philosophers。当我使用valgrind时一切都很顺利。不幸的是,当我使用控制台即时获取随机seqfaults时。有一次我的计划会成功,有一次会在一开始就打破。如果有人能指出我错误的地方以及为什么它100%成功,我将不胜感激。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define NUM_PHILOSPHERS 5
sem_t forks[NUM_PHILOSPHERS];
void *philosopher(void *param){
printf("Thread created!");
int *id = (int *)param;
int L = 0;
sem_t* Myforks[2];
int par = *id;
if(par == 4){
Myforks[0] = &forks[4];
Myforks[1] = &forks[0];
}else{
Myforks[0] = &forks[par];
Myforks[1] = &forks[par+1];
}
while(L!=5){
printf("Eat spaghetti!",*id);
sem_wait(Myforks[0]);
sem_wait(Myforks[1]);
//.....
printf("EAT spaghetti!",*id);
sem_post(Myforks[1]);
sem_post(Myforks[0]);
L=L+1;
}
pthread_exit(NULL);
}
int main(){
int i;
pthread_t threads[NUM_PHILOSPHERS];
for(i = 0; i < NUM_PHILOSPHERS; i++)
sem_init(&forks[i], 0, 1);
for(i = 0; i < NUM_PHILOSPHERS; i++)
pthread_create(&threads[i], NULL, philosopher, (void *)&i);
return 0;
}
答案 0 :(得分:3)
int i;
...
for(i = 0; i < NUM_PHILOSPHERS; i++)
pthread_create(&threads[i], NULL, philosopher, (void *)&i);
^^
将指针传递给局部变量是不行的。您将相同的地址传递给所有线程,因此存在固有的竞争条件。你指向它们指向i
,它们几乎立即增加i
。他们访问*param
时会读到什么价值?谁知道!
您希望创建一个包含NUM_PHILOSPHERS
(sic)插槽的数组,并为每个线程传递不同的地址。您还希望确保在main()
退出时不会销毁数组,即使数组全局或静态,而不是本地。