当前位置: 首页 > 知识库问答 >
问题:

多线程条件变量

督坚白
2023-03-14

我正在研究哲学家进餐问题,n位哲学家轮流思考和进餐。我想有一个版本,哲学家们会按照id的顺序进食:0,1,2,3,4。。。,但是我的线程一直被阻塞。我的线程从调用PhilosopherThread开始。

void putDownChopsticks(int threadIndex){
     //finished eating
     pindex++;
     pthread_cond_signal(&cond);
     pthread_mutex_unlock(&lock);
}

void pickUpChopsticks(int threadIndex){
     pthread_mutex_lock(&lock);
     while(pindex != threadIndex){
         pthread_cond_wait(&cond, &lock);
     } 
     //lets go eat
} 

void eating(){
     //put thread to sleep
}

void thinking(){
     //put thread to sleep
}

void* PhilosopherThread(void *x){
     int *index = x;
     thinking(); //just puts thread to sleep to simulate thinking
     pickUpChopsticks(*index);
     eating(); //just puts thread to sleep to simulate eating
     putDownChopsticks(*index);
     return NULL;
}

我想把哲学家们整理好有点麻烦。我只能在线程堵塞之前吃前2个线程。

编辑:据我所知,我这样做是对的。我首先锁定互斥锁,然后检查pindex是否是当前线程id,如果不是,线程将等待,直到pindex等于id。然后线程可以去吃,一旦完成,我们增加pindex,发出线程完成的信号,并解锁互斥锁。

共有1个答案

梁承恩
2023-03-14

此代码有时有效,有时无效。首先,由于您没有提供完整的程序,以下是我用于测试目的的缺失位:

#include <stdlib.h>
#include <pthread.h>

static pthread_cond_t cond;
static pthread_mutex_t lock;
static pindex;

/* ... your code ... */

int main () {
    int id[5], i;
    pthread_t tid[5];
    for (i = 0; i < 5; ++i) {
        id[i] = i;
        pthread_create(tid+i, 0, PhilosopherThread, id+i);
    }
    for (i = 0; i < 5; ++i) pthread_join(tid[i], 0);
    exit(0);
}

要注意的关键部分是你如何唤醒下一个哲学家:

 pthread_cond_signal(&cond);

此调用只会唤醒一个线程。但是,哪个线程由操作系统决定。因此,如果它没有唤醒应该醒来的哲学家,就没有其他哲学家被唤醒。

一个简单的解决方法是唤醒所有等待的线程,而不是只唤醒一个线程。不匹配的哲学家会回到等待中去,下一个应该去的哲学家会去。

 pthread_cond_broadcast(&cond);

然而,由于每个线程都知道应该唤醒哪个哲学家,所以您可以更改您的解决方案以允许这种情况发生。一种方法是为每个哲学家实现一个单独的条件变量,并对下一个哲学家的条件变量使用pthread\u cond\u signal()

 类似资料:
  • 我理解中的条件变量完成3件事. 1.解锁互斥锁. 2.等待通知. 3.通知到来后,再次给互斥锁上锁. 但这个不对劲,线程1开始wait之后,互斥锁应该已经解开了,线程2为什么依然没法获取互斥锁? 最后两个程序都应该打印一个数字,但实际上它们什么也不打印.

  • 管程和条件变量 原理回顾 引入了管程是为了将对共享资源的所有访问及其所需要的同步操作集中并封装起来。Hansan为管程所下的定义:“一个管程定义了一个数据结构和能为并发进程所执行(在该数据结构上)的一组操作,这组操作能同步进程和改变管程中的数据”。有上述定义可知,管程由四部分组成: 管程内部的共享变量; 管程内部的条件变量; 管程内部并发执行的进程; 对局部于管程内部的共享数据设置初始值的语句。

  • 错误:模板解析错误:不能绑定到“no-lines”,因为它不是“ion-item”的已知属性。1.如果“ion-item”是一个角组件,并且它有“no-lines”输入,那么验证它是这个模块的一部分。2.如果“ion-item”是Web组件,则将“custom_elements_schema”添加到该组件的“@ngmodule.schemas”中,以禁止该消息。3.要允许任何属性,请将“no_er

  • 我有一个包含“资源管理器”类的多线程Java应用程序。 此类提供了一个资源列表,这些资源可以作为初始化参数请求。然后检查每个文件的本地文件系统,并将确定为本地的文件添加到列表中。 当类收到资源请求时,会发生以下情况之一: > 如果资源被确定为本地资源(在列表中):请提供可以找到它的URI。 如果资源是远程的(不在列表中):安排一个工作进程来获取资源。工作进程将在任务完成时通知经理,并更新本地资源列

  • 问题内容: 在 多线程中 。我认为这是因为。这是唯一原因吗? 我知道。但为什么? 问题答案: 在多线程中,static没有意义。 恐怕你在做相反的陈述 。静态变量是一种共享资源,可用于在不同线程之间交换某些信息。而且,在访问这种共享资源时我们需要小心。因此,我们需要确保在多线程环境中对静态变量的访问是同步的。 每个线程都有自己的堆栈 这是正确的说法。堆栈仅保存局部变量,而不保存堆中的变量。静态变量

  • 条件变量 条件变量(conditional variable)的常见接口是这样的: wait:当前线程开始等待这个条件变量 notify_one:让某一个等待此条件变量的线程继续运行 notify_all:让所有等待此变量的线程继续运行 条件变量和互斥锁的区别在于,互斥锁解铃还须系铃人,但条件变量可以由任何来源发出 notify 信号。同时,互斥锁的一次 lock 一定对应一次 unlock,但条