C - 线程在等待时无限期卡住

C - Thread stuck indefinitely while waiting

我在实现“哲学家用餐”问题时遇到了问题。基本上我的程序在线程等待时陷入无限循环。我正在尝试以某种方式实施它,以便它强制执行 进食顺序 。所以哲学家 0 会先吃饭,然后是哲学家 1,依此类推。只有当我试图强制执行进餐顺序时才会出现问题,但当我让进餐顺序随机时不会出现。

这是我的强调饮食顺序的实现(陷入无限循环的那个):

void *philosopherThread(void *threadIndex){
    int philID = (int)threadIndex;
    int nextIndex = 0;
    printf("This is philosopher %d\n", philID);

    // waiting status
    thinking(philID);
    pthread_mutex_lock(&lock);

    // when the ith philosopher thread completes "thinking," the thread should check whether it is the ith philosopher's turn to eat or not prior to obtaining the chopsticks
    // If nextIndex==philID, the ith philosopher will grab both chopsticks and begin eating
    if(philID ==nextIndex){
        pickUpChopsticks(philID);
        eating(philID);
        putDownChopsticks(philID);
    }
    // waits on conditional variable
    while(nextIndex != philID){
        pthread_cond_wait(&var, &lock);
    }

    pickUpChopsticks(philID);
    eating(philID);
    putDownChopsticks(philID);

    // after finished eating it will  increment the value of nextIndex and release the lock to wake up all threads that are waiting on the conditional variable
    nextIndex++;
    pthread_cond_broadcast(&var);
    return(NULL);
}

作为参考,这是我的实现,其中不强调进食顺序(这个有效,没有无限循环)

void *philosopherThread(void *threadIndex){
    int philID = (int)threadIndex;
    printf("This is philosopher %d\n", philID);

    // waiting status
    thinking();

    // acquire locks
    pickUpChopsticks(philID);
    eating();

    // release lock
    putDownChopsticks(philID);

    return(NULL);
}

所以我需要有关第一个代码的帮助,以便它不再陷入无限循环。任何帮助将不胜感激。

三个问题:

  • 每个线程都有自己的nextIndex。应该只有一个。

  • 线程在退出时仍然持有互斥锁。

  • mutex_lock和cond_wait之间的“距离”令人担忧。中间是什么???你在等着吃饭,所以应该没有其他表演了。

static int nextIndex = 0;

void *philosopherThread(void *threadIndex){
    int philID = (intptr_t)threadIndex;           // Use intptr_t on the outside too.
    printf("This is philosopher %d\n", philID);

    // We're thinking.
    thinking(philID);

    // Wait for our turn.
    pthread_mutex_lock(&lock);
    while(nextIndex != philID)
        pthread_cond_wait(&var, &lock);

    // We're eating.
    pickUpChopsticks(philID);
    eating(philID);
    putDownChopsticks(philID);

    // We're back to thinking.
    thinking(philID);

    // Make it someone else's turn, and have all of the
    // waiting philosophers check if its their turn to eat.
    nextIndex++;
    pthread_cond_broadcast(&var);
    pthread_mutex_unlock(&lock);

    return NULL;
}