我正在尝试使用资源层次结构解决方案在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()退出时不会破坏该数组,即,将数组设为全局或静态,而不是局部。

10-08 01:16