带有Pthread的C中餐饮哲学家的细分错误

问题描述 投票:0回答:1

我在用餐哲学家的运动中遇到了这种分割错误问题,每个哲学家只有一个线程,我无法管理。每个线程会随机思考一段时间,并且与进食相同。每个哲学家都可以用两个叉子吃饭,他必须拿起两个叉子来吃饭。为了避免死锁,我对分叉进行了分类。具有奇数的哲学家首先选择右叉。我使用了一个全局信号量,该信号量是在main开始时用函数init初始化的。请问有人可以帮助我吗?我试图放一些fprintf(stderr,“ HERE \ n”),但是由于并发,我找不到问题。这是代码

'''

//global array of semaphore
 pthread_mutex_t *mtx;

//intialize array of semaphore
void init(pthread_mutex_t *mtx){
    mtx=malloc(N*sizeof(pthread_mutex_t));
    if(!mtx){
      perror("malloc fallita\n");
      exit(EXIT_FAILURE);
   }
   for(int i=0;i<N;i++){
     if(pthread_mutex_init(&mtx[i],NULL) != 0){
         perror("init fallita\n");
         exit(EXIT_FAILURE);
     }
   }
 } 



void eat(unsigned int *seed){
  long r = rand_r(seed) % 800000;
  struct timespec t={0,r};
  nanosleep(&t,NULL);
}

void think(unsigned int *seed){
long r = rand_r(seed) % 1000000;
struct timespec t={0,r};
nanosleep(&t,NULL);
}


void *filosofo(void *arg){
    unsigned int id = *((unsigned int*)arg);
    unsigned int seed=id;
    int left = id % N;
    int right = id-1;
    while(1){
        think(&seed);
        if(id % 2){ //il filosofo di indice dispari prende prima la forchetta di destra
            pthread_mutex_lock(&mtx[right]);
            pthread_mutex_lock(&mtx[left]);
            eat(&seed);
            pthread_mutex_unlock(&mtx[left]);
            pthread_mutex_unlock(&mtx[right]);
        }else{ //il filosofo di indice pari prende prima la forchetta a sinista
            pthread_mutex_lock(&mtx[left]);
            pthread_mutex_lock(&mtx[right]);
            eat(&seed);
            pthread_mutex_unlock(&mtx[right]);
            pthread_mutex_unlock(&mtx[left]);
        }
    }

    pthread_exit(NULL);
}



int main(void){
    init(mtx);
    //array of N philosophers
    pthread_t *th;
    th = malloc(N*sizeof(pthread_t));
    if(!th){
        perror("Malloc fallita\n");
        exit(EXIT_FAILURE);
    }
    for(unsigned int i=0;i<N;i++){
        if(pthread_create(&th[i],NULL,filosofo,(void*)(intptr_t)i) != 0){
            perror("create fallita\n");
            exit(EXIT_FAILURE);
        }
    }

    for(unsigned int i=0;i<N;i++){
        if(pthread_join(th[i],NULL) == -1){
            perror("join fallita\n");
        }
    }

    free(th);
    free(mtx);

    return 0;

}

'''

c segmentation-fault pthreads
1个回答
0
投票

您需要使init的指针指向互斥量的指针以进行初始化。当前,全局mtx尚未更改。

大致情况:

void init(pthread_mutex_t **mtx){ // pointer to pointer
    *mtx=malloc(N*sizeof(pthread_mutex_t)); // dereference
    if(!*mtx){
      perror("malloc fallita\n");
      exit(EXIT_FAILURE);
   }
   for(int i=0;i<N;i++){
     if(pthread_mutex_init(&(*mtx)[i],NULL) != 0){ // pointer acrobatics
         perror("init fallita\n");
         exit(EXIT_FAILURE);
     }
   }
 }

然后将指针传递到mtx中的全局main

int main(void){
    init(&mtx);

我建议在init中以不同的方式命名全局互斥锁和本地互斥锁,以免再次使您感到困惑。

© www.soinside.com 2019 - 2024. All rights reserved.