我在用餐哲学家的运动中遇到了这种分割错误问题,每个哲学家只有一个线程,我无法管理。每个线程会随机思考一段时间,并且与进食相同。每个哲学家都可以用两个叉子吃饭,他必须拿起两个叉子来吃饭。为了避免死锁,我对分叉进行了分类。具有奇数的哲学家首先选择右叉。我使用了一个全局信号量,该信号量是在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;
}
'''
您需要使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
中以不同的方式命名全局互斥锁和本地互斥锁,以免再次使您感到困惑。