哲学家进餐问题

    技术2022-07-11  96

    问题描述:

    问题描述: 5个哲学家围坐在一个圆桌上,每两个哲学家之间都有一只筷子,哲学家平时进行思考,只有当他们饥饿时,才拿起筷子吃饭。规定每个哲学家只能先取其左边筷子,然后取其右边筷子,然后才可以吃饭。

    #include<stdio.h>//c语言中主要的函数库 #include<stdlib.h>//stdlib 头文件里包含了C、C++语言的最常用的系统函数 #include<pthread.h>//线程对应函数库 #include<iostream>//输入输出流,有输入输出对应的库函数 #include<unistd.h>//对于类 Unix 系统,unistd.h 中所定义的接口通常都是大量针对系统调用的封装 //是 C 和 C++ 程序设计语言中提供对 POSIX 操作系统 API 的访问功能的头文件的名称。 #include<semaphore.h>//信号量对应的库函数 #define N 5 //5位哲学家 #define LEFT i //左边筷子 #define RIGHT (i+1)%N //右边筷子 using namespace std; //信号量机制 class Semaphore{ private: sem_t sem; public: Semaphore(int value=1){//这里是5根筷子,五位哲学家竞争,筷子是临界资源。所以每个对象都是 1 sem_init(&sem,0,value); } void P(){ sem_wait(&sem);//P操作 "--"操作 } void V(){ sem_post(&sem);//V操作 "++" 操作 } }; //全局变量 //信号量机制 Semaphore mutex[N];//互斥信号量数组 1 1 1 1 1 //线程 pthread_t thread[N];//线程数组 5个线程 int id[N]; //线程标号 int add=0;//增量 增加到30就面条吃完了 void* solve(void*param){ int i =*((int*)param);// param 是形参,实参是线程 id[N]的地址 , 这里用int*指针指向它,再取值 while(true){ if(add>=30){ cout<<"哲学家"<<i<<"面条吃完了!!"<<endl;//每个人的面规定是30下 break; } cout<<"哲学家"<<i<<"正在思考"<<endl;//思考不会死锁,只在进餐时有可能死锁 if(i%2==0){ mutex[LEFT].P(); mutex[RIGHT].P(); cout<<"哲学家"<<i<<"进餐"<<endl; add++; // cout<<add<<endl; mutex[RIGHT].V(); mutex[LEFT].V(); }else{ //*********下面可能会产生死锁,原因是: 如果所有哲学家都同时拿起右边的筷子,大家都因为没能达到自己要求而不肯释放自己的资源 //所以会产生死锁。 mutex[RIGHT].P(); mutex[LEFT].P(); cout<<"哲学家"<<i<<"进餐"<<endl; add++; //cout<<add<<endl; mutex[LEFT].V(); mutex[RIGHT].V(); // } sleep(1); // 让线程休眠的目的是使线程让出CPU的使用权.当线程休眠时,会将CPU资源的使用 //单位是毫秒 //交给其他线程,以便能够线程之间的轮换调用.当休眠一定时间后,线程就会苏醒,然后进入准备状态等待执行. } } } //创建线程 void thread_create() { int tmp; for(int i=0; i<N; i++){//5位哲学家 //*************重点 // 有四个参数,第一个参数是线程标识符,第二个参数是线程的属性(null是指线程需要手动释放,需要相关函数,如果是其他线程会分离出来会自己释放), // 第三个参数是处理函数(让线程执行操作),第四个参数是处理函数的形参(类型是 void*) tmp=pthread_create(&thread[i],NULL,solve,&id[i]);// if(tmp!=0){//pthread_create有返回值 等于0是正常情况,如果错误返回值是其他 cout<<"线程"<<i<<"结束"<<endl;//正常的话这里是不执行的 } } } //线程等待 void thread_wait(){//线程唤醒机制,唤醒处于睡眠中的线程,所以处理函数中的sleep()函数和这里是匹配的 for(int i=0; i<N; i++){ pthread_join(thread[i],NULL);//线程的标识符和线程的属性 } } int main(){ for(int i=0; i<N; i++){//5位哲学家装入到数组里面,通过下标来操作 id[i]=i;//哲学家编号数组 } thread_create();//线程创建 thread_wait();//线程等待 return 0; }

    今日分享

    运行结果:

    Processed: 0.010, SQL: 9