我正在尝试使用资源层次结构解决方案在C中实现餐饮哲学家。当我使用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;
}
最佳答案
int i;
...
for(i = 0; i < NUM_PHILOSPHERS; i++)
pthread_create(&threads[i], NULL, philosopher, (void *)&i);
^^
将指针传递给局部变量将不起作用。您正在向所有线程传递相同的地址,因此存在一个固有的竞争条件。您将它们指向
i
的指针,然后几乎立即增加i
即可。访问*param
时将读取什么值?谁知道!您将要创建一个带有
NUM_PHILOSPHERS
(sic)插槽的数组,并将一个不同的地址传递给每个线程。您还需要确保在main()
退出时不会破坏该数组,即,将数组设为全局或静态,而不是局部。