【问题标题】:C - Thread stuck indefinitely while waitingC - 线程在等待时无限期卡住
【发布时间】:2021-10-13 14:13:34
【问题描述】:

我在实施“餐饮哲学家”问题时遇到了麻烦。基本上我的程序在线程等待时陷入无限循环。我正在尝试以某种方式实现它,以便它强制执行进食顺序。所以哲学家 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);
}

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

【问题讨论】:

  • mutex_lock 和 cond_wait 之间的“距离”令人担忧。中间是什么???此外,您在互斥锁锁定的情况下退出线程。
  • 最下面的可能会死锁。它绝对不会“工作”。

标签: c multithreading pthreads thread-synchronization


【解决方案1】:

三个问题:

  • 每个线程都有自己的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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-23
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 2012-12-18
    • 2020-06-22
    相关资源
    最近更新 更多