精华内容
下载资源
问答
  • 哲学家就餐问题C语言源文件,操作系统课程论文要求,进程同步模拟
  • 假设有五位哲学家围坐在一张圆形餐桌旁,做以下两件事情之一:吃饭,或者思考。吃东西的时候,他们就停止思考,思考的时候也停止吃东西。餐桌中间有一大碗意大利面,每两个哲学家之间有一只餐叉。因为用一只餐叉很难...

    问题描述

    假设有五位哲学家围坐在一张圆形餐桌旁,做以下两件事情之一:吃饭,或者思考。吃东西的时候,他们就停止思考,思考的时候也停止吃东西。餐桌中间有一大碗意大利面,每两个哲学家之间有一只餐叉。因为用一只餐叉很难吃到意大利面,所以假设哲学家必须用两只餐叉吃东西。他们只能使用自己左右手边的那两只餐叉。
    哲学家位置
    分析:最多4个人拿起筷子,则可以避免死锁。设置信号量控制。

    C语言实现

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <pthread.h>
    #include <semaphore.h>
    
    pthread_mutex_t chopsticks[6];  //5个筷子的互斥锁,0不用,使用1~5号
    
    sem_t s;         //最多四个人拿起筷子,则不会发生死锁!
    
    void deal(char ch){
        int left, right;  //左右筷子的编号,i号筷子在i号哲学家左侧;哲学家逆时针坐
        //给筷子编号
        if(ch == 'A') { left = 1; right = 5; }
        else if(ch == 'B') { left = 2; right = 1; }
        else if(ch == 'C') { left = 3; right = 2; }
        else if(ch == 'D') { left = 4; right = 3; }
        else { left = 5; right = 4; }
    
        while(1){
            sleep(1);  //思考
            sem_wait(&s);
            pthread_mutex_lock(&chopsticks[left]);  //拿起左手的筷子,上锁
            printf("Left chopstick(pick) : %d\n", left);
            pthread_mutex_lock(&chopsticks[right]);  //拿起右手边有筷子
            printf("Right chopstick(pick) : %d\n", right);
    
            //吃饭
            printf("---EATING TIME FOR : %c---\n", ch);
            sleep(1);
    
            //吃完饭
            pthread_mutex_unlock(&chopsticks[left]);  //放下左手的筷子
            printf("Left chopstick(put) : %d\n", left);
            pthread_mutex_unlock(&chopsticks[right]);  //放下右手的筷子
            printf("Right chopstick(put) : %d\n", right);
            sem_post(&s);
        }
    }
    
    int main(){
    
        //初始化锁
    	int i = 0;
        for(i = 0; i < 6; ++i) 
    		pthread_mutex_init(&chopsticks[i], NULL);
    
        //初始化信号量为4
        sem_init(&s,0,4);
    
        //创建5个哲学家线程
        pthread_t A, B, C, D, E;
        pthread_create(&A, NULL, deal, 'A');  
            //&A 线程指针,NULL 线程类型,deal 调用函数,‘A’ 函数参数
        pthread_create(&B, NULL, deal, 'B');
        pthread_create(&C, NULL, deal, 'C');
        pthread_create(&D, NULL, deal, 'D');
        pthread_create(&E, NULL, deal, 'E');
    
        //线程同步
        pthread_join(A, NULL);
        pthread_join(B, NULL);
        pthread_join(C, NULL);
        pthread_join(D, NULL);
        pthread_join(E, NULL);
    
        //销毁信号量
        sem_destroy(&s);
        return 0;
    } 
    
    展开全文
  • 哲学家就餐问题C语言实现(涉及多线程、信号量等)1、实验原理2、实验内容3、代码部分3.1 重要代码展示3.2 源码3.3 运行结果展示 1、实验原理   由Dijkstra提出并解决的哲学家进餐问题(The Dinning Philosophers ...

    哲学家就餐问题C语言实现(涉及多线程、信号量等)

    1、实验原理

      由Dijkstra提出并解决的哲学家进餐问题(The Dinning Philosophers Problem)是典型的同步问题。该问题是描述有五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五只筷子,他们的生活方式是交替地进行思考和进餐。平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有在他拿到两只筷子时才能进餐。进餐完毕,放下筷子继续思考。

    2、实验内容

      显示出每个哲学家的工作状态,如吃饭,思考。连续运行30次以上都未出现死锁现象。

    3、代码部分

    3.1 重要代码展示

    重要代码展示:
    (1)初始化int型数组ID[NUM]标识线程ID号,用于后续传参;初始化信号量数组sem_chopsticks[NUM]模拟五根筷子;初始化信号量sem_eaters=4,用来控制同时可拿起筷子的最大人数。

    int ID[NUM]={0,1,2,3,4};
    sem_t sem_chopsticks[NUM];
    sem_t sem_eaters;
    sem_init(&sem_eaters,0,NUM-1)
    

    (2)线程的例程处理函数,先等待信号量sem_eaters,再等待信号量sem_chopsticks[pthread_id],这两个信号量不为零说明此时同时拿起筷子的人数小于4,且该哲学家编号相同的筷子(记为左筷子)可以被拿起,所以拿起左子,然后等待右筷子sem_chopsticks[pthread_id+1]信号量,拿到右筷子后便可以进餐,随机释放上述三个信号量。

    void philosopher(void * ptid){
        int pthread_id = *(int *)ptid%NUM;
        printf("%d philosopher is thinking...\n",(int)pthread_id);
        sem_wait(&sem_eaters);
        sem_wait(&sem_chopsticks[pthread_id]);
        printf("%d philosopher takes chopstick %d...\n",(int)pthread_id,(int)pthread_id);
        sem_wait(&sem_chopsticks[(pthread_id+1)%NUM]);
        printf("%d philosopher takes chopstick %d...\n",(int)pthread_id,((int)pthread_id+1)%NUM);
    printf("%d philosopher is eating, %d philosopher had already dined.\n",(int)pthread_id,eaters_num);
        sem_post(&sem_chopsticks[(pthread_id+1)%NUM]);
        sem_post(&sem_chopsticks[pthread_id]);
        sem_post(&sem_eaters);
        eaters_num++;
        printf("%d philosopher had dined, by now %d philosopher had already dined.\n",(int)pthread_id,eaters_num);}
    

    (3)循环创建5个线程模拟五位哲学家,线程例子程函数为philosopher,并传入参数ID[i]标识线程的ID。

    pthread_t philosopher_threads[NUM];
            sem_signal_init();
            for ( i= 0; i < NUM; i++) {
                printf("%d times\n",i);
                if (pthread_create(&philosopher_threads[i], NULL, (void *)&philosopher,&ID[i]) != 0){
                    perror("oops:pthread_create error!");
                    exit(1);
                }
    

    3.2 源码

    #include <unistd.h>
    #include "pthread.h"
    #include "stdio.h"
    #include "stdlib.h"
    #include "semaphore.h"
    
    #define NUM 5
    int ID[NUM]={0,1,2,3,4};
    sem_t sem_chopsticks[NUM];
    sem_t sem_eaters;
    int eaters_num=0;
    void sem_signal_init(){
        int i;
        for (i=0; i<NUM; i++){
            if (sem_init(&sem_chopsticks[i],0,1) == -1){
                perror("oops:em_init error!");
                exit(1);
            }
        }
        if (sem_init(&sem_eaters,0,NUM-1) == -1){
            perror("oops:em_init error!");
            exit(1);
        }
    }
    
    void philosopher(void * ptid){
        int pthread_id = *(int *)ptid%NUM;
        printf("%d philosopher is thinking...\n",(int)pthread_id);
        sem_wait(&sem_eaters);
        sem_wait(&sem_chopsticks[pthread_id]);
        printf("%d philosopher takes chopstick %d...\n",(int)pthread_id,(int)pthread_id);
        sem_wait(&sem_chopsticks[(pthread_id+1)%NUM]);
        printf("%d philosopher takes chopstick %d...\n",(int)pthread_id,((int)pthread_id+1)%NUM);
        printf("%d philosopher is eating, %d philosopher had already dined.\n",(int)pthread_id,eaters_num);
        sem_post(&sem_chopsticks[(pthread_id+1)%NUM]);
        sem_post(&sem_chopsticks[pthread_id]);
        sem_post(&sem_eaters);
        eaters_num++;
        printf("%d philosopher had dined, by now %d philosopher had already dined.\n",(int)pthread_id,eaters_num);
    
    }
    
    int main(){
        int i,l,j,k;
        for (l = 0; l < 1000; ++l) {
            printf("**********************%d times try ******************************",l+1);
            pthread_t philosopher_threads[NUM];
            sem_signal_init();
            for ( i= 0; i < NUM; i++) {
                printf("%d times\n",i);
                if (pthread_create(&philosopher_threads[i], NULL, (void *)&philosopher,&ID[i]) != 0){
                    perror("oops:pthread_create error!");
                    exit(1);
                }
            }
    
            for ( j = 0; j < NUM; j++) {
                pthread_join(philosopher_threads[j], NULL);
            }
            sem_destroy(&sem_eaters);
            for (k = 0; k < NUM ; ++k) {
                sem_destroy(&sem_chopsticks[k]);
            }
            eaters_num = 0;
    //        sleep(2);
        }
    
        return 0;
    }
    
    

    3.3 运行结果展示

      本程序用五个线程模拟五位哲学家,用五个sem_t型信号量模拟五根筷子(临界资源),解题的思想是:每次让每位哲学家优先拿起自己左边的筷子,并限制最多有四个人同时拿起筷子,从而避免了死锁情况,该程序模拟五个哲学家进餐一次的情况,并重复模拟了1000次以上来检验是否出现死锁情况,经检验程序运行正常,没有出现死锁状况,上述图片仅展示了第1次和第1000次的情况。

    在这里插入图片描述

    展开全文
  • 代码块复杂度大家可以画10分钟 100知名企业今年来iOS面试题合集:你要的这里都有;企业要的这里也有;从基础开始到进阶、深入底层整理出188个面试题,全是干货目录展示:1、swift和oc的区别2、编译链接3、...

    挺久之前过了一遍CSP的安全策略,很多人把它喻为XSS***的终结者,因为这种策略不再像传统只靠各种正则和特征匹配来识别跨站***Payload,而是直接从协议层把一些存在安全隐患的用法默认给干掉了,把同源同域更发挥到了极致。之前把一些内容整理到了txt里,发在这里备忘一下吧:)

    1)CSP策略在默认的情况下是不允许使用data URIs资源的,如果要使用,那么需要显示的

    笔者与近日从国内资深互联网应用安全提供商知道创宇安全研究团队处得悉,目前有一项严重危害用户隐私的漏洞刚刚被发现,包括旅游,招聘,娱乐,SNS交友,各大电商等各类网站均会被影响。经知道创宇安全研究团队测试,该安全漏洞在国内使用第三方登录机制的网站中普遍存在,甚至知名的安全厂商360的网站平台以及360浏览器也存在这个问题。由于此类***不受同源策略等浏览器的安全限制,且不易被

    本文主要讲解代码注入的两种方式:FrameWork注入、dylib注入

    本文主要介绍通过shell脚本进行应用重签名

    本文主要介绍重签名的几种方式,以及如何对应用进行重签名

    本文主要讲解什么是代码签名,以及iOS中的应用签名

    本文主要是对称算法的终端演示+代码演示

    本文主要介绍对称算法的基本概念

    本文主要理解OC对象反汇编,以及block常见类型的反汇编

    本文主要讲解编译器的优化以及指针的汇编

    本文主要讲解Switch的汇编代码

    本文的主要目的是理解汇编中全局变量、常量的存储,以及如何将if、while等汇编代码还原成高级代码

    本文主要是讲解函数的参数、返回值、局部变量在汇编中是如何存储,以及CPSR标志寄存器

    本来想着写界面优化的,但是因为前段时间项目比较忙,就一直没弄!加上最近项目里也在整理组件化的东西,所以也就决定写篇关于组件化的文章。

    [iOS初级教程之二]DeepLink实践一、唤醒iOS应用程序的几种方式唤醒应用是iOS开发中常见的技术,应用唤醒的方式有多种,概括下来,可以分为如下几类:直接打开App通知唤醒scheme唤醒UniversalLinks唤醒直接打开App是最直接的唤醒应用程序的方式,以iPhone为例,可以从主屏幕、搜索推荐、应用库等场景中进行打开。当用户收到通知消息时,点击通知栏的通知消息也可以唤醒应用程序

    两数之和解决方案无重复字符的最长字串(2)"滑动窗口法"优化解决关键词介绍解题思路复杂度分析无重复字符的最长字串(3)优化"滑动窗口"解决代码块ASCII 128码 思路代码块最大回文子串解题思路找到字符串的最长公共子串动态编程解决方案复杂度代码块学习建议最大回文子串(2)我们上面分享的不管从时间复杂度还是空间复杂度,都是颇为浪费的?难道没有更优解决方案?肯定是有的!代码块复杂度大家可以画10分钟

    100家知名企业今年来iOS面试题合集:你要的这里都有;企业要的这里也有;从基础开始到进阶、深入底层整理出188个面试题,全是干货目录展示:1、swift和oc的区别2、编译链接3、synthesize & denamic4、在项目开发中常用的开发工具有哪些?5、UITableView & UICollection6、NSProxy & NSObject7、Object &

    1、Objective-C的类可以多重继承么?可以采用多个协议么?答:不可以多重继承,可以采用多个协议。2、#import和#include的区别是什么?#import<> 跟 #import""有什么区别?import能避免头文件被重复包含的问题:1) 一般来说,导入objective c的头文件时用#import,包含c/c++头文件时用#include。使用include要注意重

    HarmonyOS(鸿蒙)技术社区是由51CTO和华为共同打造的综合性开发和应用技术社区。作为华为的官方战略合作伙伴,51CTO将多年的社区运营经验与华为的技术赋能相结合,为开发者提供高质量有深度的HarmonyOS(鸿蒙)学习交流平台。

    展开全文
  • 场景: 原版的故事里有五个哲学家(不过我们写的程序可以有N个哲学家),这些哲学家们只做两件事--思考和吃饭,他们思考的时候不需要任何共享资源,...现在引入问题的关键:这些哲学家很穷,只买得起五根筷子。他...

    场景:

     

    原版的故事里有五个哲学家(不过我们写的程序可以有N个哲学家),这些哲学家们只做两件事--思考和吃饭,他们思考的时候不需要任何共享资源,但是吃饭的时候就必须使用餐具,而餐桌上的餐具是有限的,原版的故事里,餐具是叉子,吃饭的时候要用两把叉子把面条从碗里捞出来。很显然把叉子换成筷子会更合理,所以:一个哲学家需要两根筷子才能吃饭。

    现在引入问题的关键:这些哲学家很穷,只买得起五根筷子。他们坐成一圈,两个人的中间放一根筷子。哲学家吃饭的时候必须同时得到左手边和右手边的筷子。如果他身边的任何一位正在使用筷子,那他只有等着。

    假设哲学家的编号是A、B、C、D、E,筷子编号是1、2、3、4、5,哲学家和筷子围成一圈如下图所示:

     
     

     

    1. #include <stdio.h>  
    2. #include <stdlib.h>  
    3. #include <memory.h>  
    4. #include <pthread.h>  
    5. #include <errno.h>  
    6. #include <math.h>  
    7. //筷子作为mutex  
    8. pthread_mutex_t chopstick[6] ;  
    9. void *eat_think(void *arg)  
    10. {  
    11.     char phi = *(char *)arg;  
    12.     int left,right; //左右筷子的编号  
    13.     switch (phi){  
    14.         case 'A':  
    15.             left = 5;  
    16.             right = 1;  
    17.             break;  
    18.         case 'B':  
    19.             left = 1;  
    20.             right = 2;  
    21.             break;  
    22.         case 'C':  
    23.             left = 2;  
    24.             right = 3;  
    25.             break;  
    26.         case 'D':  
    27.             left = 3;  
    28.             right = 4;  
    29.             break;  
    30.         case 'E':  
    31.             left = 4;  
    32.             right = 5;  
    33.             break;  
    34.     }  
    35.   
    36.     int i;  
    37.     for(;;){  
    38.         usleep(3); //思考  
    39.         pthread_mutex_lock(&chopstick[left]); //拿起左手的筷子  
    40.         printf("Philosopher %c fetches chopstick %d\n", phi, left);  
    41.         if (pthread_mutex_trylock(&chopstick[right]) == EBUSY){ //拿起右手的筷子     
    42.             pthread_mutex_unlock(&chopstick[left]); //如果右边筷子被拿走放下左手的筷子  
    43.             continue;  
    44.         }  
    45.           
    46.     //  pthread_mutex_lock(&chopstick[right]); //拿起右手的筷子,如果想观察死锁,把上一句if注释掉,再把这一句的注释去掉  
    47.         printf("Philosopher %c fetches chopstick %d\n", phi, right);  
    48.         printf("Philosopher %c is eating.\n",phi);  
    49.         usleep(3); //吃饭  
    50.         pthread_mutex_unlock(&chopstick[left]); //放下左手的筷子  
    51.         printf("Philosopher %c release chopstick %d\n", phi, left);  
    52.         pthread_mutex_unlock(&chopstick[right]); //放下左手的筷子  
    53.         printf("Philosopher %c release chopstick %d\n", phi, right);  
    54.   
    55.     }  
    56. }  
    57. int main(){  
    58.     pthread_t A,B,C,D,E; //5个哲学家  
    59.   
    60.     int i;  
    61.     for (i = 0; i < 5; i++)  
    62.         pthread_mutex_init(&chopstick[i],NULL);  
    63.     pthread_create(&A,NULL, eat_think, "A");  
    64.     pthread_create(&B,NULL, eat_think, "B");  
    65.     pthread_create(&C,NULL, eat_think, "C");  
    66.     pthread_create(&D,NULL, eat_think, "D");  
    67.     pthread_create(&E,NULL, eat_think, "E");  
    68.   
    69.     pthread_join(A,NULL);  
    70.     pthread_join(B,NULL);  
    71.     pthread_join(C,NULL);  
    72.     pthread_join(D,NULL);  
    73.     pthread_join(E,NULL);  
    74.     return 0;  
    75. }  

    注意:

     

    1. gcc编译时,加上-lphread选项,例:gcc eating.c -lpthread

    2.pthread_create的第四个参数是void *类型,我一开始传一个char类型,即'A',就会发生段错误。但改成char *,即“A”就没问题了。

    3.usleep是毫秒级的阻塞

    转载于:https://www.cnblogs.com/pigdragon/p/6951475.html

    展开全文
  • 哲学家就餐问题是一个经典的同步问题,这不是因为其本身的实际重要性,也不是因为计算机科学家不喜欢哲学家,而是因为它是大量并发控制问题的一个例子。这个代表型的例子满足:在多个进程之间分配多个资源,而且不会...
  • printf("哲学家%d正在就餐...\n", *current); printf("哲学家放下左边%d筷子\n", chopstick); chopstick = (chopstick + 1) % 5; printf("哲学家放下右边%d筷子\n\n", chopstick); Sleep(2000); ReleaseMutex...
  • 哲学家就餐问题哲学家就餐问题C语言描述C语言描述哲学家就餐问题C语言哲学哲学家就餐问题C语言描述家就餐问题C语言描述描述哲学家就餐问题C语言描述
  • C语言描述的哲学家家就餐问题的实现...
  • 哲学家就餐问题-C语言讲解

    千次阅读 2019-04-13 01:55:13
    原博客网址:哲学家就餐问题-C语言讲解 哲学家问题是操作系统中同步互斥的经典问题。通常使用信号量,管程的方式。这篇文章将会简要介绍问题的定义和类似服务生解法。并且用c语言实现解法。 问题描述: 五个哲学家...
  • C语言解决哲学家就餐问题
  • c语言模拟操作系统中哲学家就餐问题并实现。可在vs下运行
  • 文档为实验报告,运行环境是ubantu,文档包含哲学家就餐问题的代码,使用三种方法解决哲学家就餐问题,顺序资源法,加房间法和P_sim法,希望对大家有帮助
  • 本文简单介绍了哲学家就餐问题,并进行了简单实现。
  • 关键问题: 能为每一个哲学家写一段描述其行为的程序,且决不会死锁吗? 提示: 如果五位哲学家同时拿起左面的叉子,就没有人能够拿到他们各自右面的叉子,于是...解决问题的关键在于,必须保证任意一位哲学家只有.
  • 哲学家就餐问题C语言实现)

    万次阅读 多人点赞 2012-04-22 18:29:48
    场景: 原版的故事里有五个哲学家(不过我们写的程序可以有N个哲学家),这些哲学家们只做两件事--思考和吃饭,他们思考的时候不需要任何共享资源,...现在引入问题的关键:这些哲学家很穷,只买得起五根筷子。他们
  • /*------------哲学家进餐问题--------*/ #include&lt;pthread.h&gt; #include&lt;semaphore.h&gt; #include&lt;unistd.h&gt; //用于sleep() /* * 定义变量及含义如下 */ #define N 5 //...
  • C语言版—操作系统中的哲学家就餐问题C语言版—操作系统中的哲学家就餐问题
  • C语言哲学家就餐问题

    千次阅读 2016-09-19 14:38:42
    场景: 原版的故事里有五个哲学家(不过我们写的程序可以有N个哲学家),这些哲学家们只做两件事--思考和吃饭,他们思考的时候不需要任何共享资源,但是吃饭...现在引入问题的关键:这些哲学家很穷,只买得起五
  • 并行程序设计第4次作业——哲学家就餐问题一、问题描述五个沉默的哲学家围坐在一个圆桌旁,桌上放着几碗意大利面。叉子被放置在每一对相邻的哲学家之间。每个哲学家必须交替地思考和进餐。然而,哲学家只能在有左右...
  • 这是一个描叙哲学家进餐问题的代码。。。。。。C语言写额

空空如也

空空如也

1 2 3 4 5 ... 14
收藏数 265
精华内容 106
关键字:

哲学家就餐问题c语言

c语言 订阅