哲学家问题是操作系统中资源分配的经典问题

linux平台下的系统api不同于Windows下的实现

要求:一个正确的哲学家程序(不会发生死锁)

一个错误的哲学家程序(会发生死锁)

系统环境:ElementaryOS

wrong.c

#include<stdio.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<sys/types.h>
#include<unistd.h>
#include<errno.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/wait.h>
#define DELAY (rand() % 5 + 1)
#define ERR_EXIT(m) \
do { \
perror(m); \
exit(EXIT_FAILURE); \
} while() union semun
{
int val; // Value for SETVAL
struct semid_ds *buf; //Buffer for IPC_STAT, IPC_SET
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO (Linux-specific) */
};
//semid ! this is the number of share memory
int semid;
//waiting for fork here
//left and right = the number of sourses
void wait_for_1fork(int no)
{
int left = no;
//system defined struct
//"first":the current number of pro
//"second":resourses -1:wait cannot use;+1:can use
//"thired":?
struct sembuf buf[] =
{
{left, -, },
};
//semop do wait or signal (p/v)
//"first": the number of share memory pro
//"second":the first point of struct
//"third":the number of signal to complete
semop(semid, buf, );
}
void wait_for_2fork(int no)
{
int right = (no + ) % ;
//system defined struct
//"first":the current number of pro
//"second":resourses -1:wait cannot use;+1:can use
//"thired":?
struct sembuf buf[] =
{
{right, -, }
};
//semop do wait or signal (p/v)
//"first": the number of share memory pro
//"second":the first point of struct
//"third":the number of signal to complete
semop(semid, buf, );
}
void free_1fork(int no)
{
int left = no;
//system defined struct
//"first":the current number of pro
//"second":resourses -1:wait cannot use;+1:can use
//"thired":?
struct sembuf buf[] =
{
{left, , },
};
semop(semid, buf, );
}
void free_2fork(int no)
{
int right = (no + ) % ;
//system defined struct
//"first":the current number of pro
//"second":resourses -1:wait cannot use;+1:can use
//"thired":?
struct sembuf buf[] =
{
{right, , }
};
semop(semid, buf, );
}
void philosopere(int num)
{
srand(getpid());
for (; ;)
{
//printf("%d is thinking\n", num);
printf("\033[36m%d is thinking\n\033[0m", num);
if(num!=)
sleep(DELAY);
//printf("%d is hungry\n", num);
wait_for_1fork(num);
//printf("%d pick up left chopsticks\n", num);
printf("\033[31m%d pick up left chopsticks\n\033[0m", num);
sleep(DELAY);
sleep(DELAY);
wait_for_2fork(num);
//printf("%d pick up right chopsticks\n", num);
printf("\033[34m%d pick up right chopsticks\n\033[0m", num);
//printf("%d is eating\n", num);
sleep(DELAY);
free_1fork(num);
//printf("%d return left chopsticks\n", num);
printf("\033[33m%d return left chopsticks\n\033[0m", num);
sleep(DELAY);
free_2fork(num);
//printf("%d return right chopsticks\n", num);
printf("\033[37m%d return right chopsticks\n\033[0m", num);
}
}
int main()
{
//use IPC to connect between processes . A new share memory
//semget() return the number of share memory
//new signal key=0 and never change .So not use key
//"first":use IPC_PRIVATE to share memory between relation processes
//"second":(size_t)naxSize
//"third":(int flag)private:666--read and write ; IPC_CREAT creat new memory
semid = semget(IPC_PRIVATE, , IPC_CREAT | );
if (semid == -)
ERR_EXIT("semget");
union semun su;
su.val = ;
for (int i = ; i < ; i++)
{
//creat a new object on "semid"
//use i to depart 5 processes
semctl(semid, i, SETVAL, su);
}
int no = ;
//pid_t (Process ID _ Type) Just like int
pid_t pid;
for (int i = ; i < ; i++)
{
//use fork() to make a copy of father process named with child pro
//father.pid>0 and child.pid=0
//after for loop will exist a father and five childs(0-4)
pid = fork();
if (pid == -)
ERR_EXIT("fork");
if (pid == )
{
no = i;
//break the child process loop to run the philosopere
break;
}
}
philosopere(no);
return ;
}

right.c

#include<stdio.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<sys/types.h>
#include<unistd.h>
#include<errno.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/wait.h>
#define DELAY (rand() % 5 + 1)
#define ERR_EXIT(m) \
do { \
perror(m); \
exit(EXIT_FAILURE); \
} while() union semun
{
int val; // Value for SETVAL
struct semid_ds *buf; //Buffer for IPC_STAT, IPC_SET
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO (Linux-specific) */
};
//semid ! this is the number of share memory
int semid;
//waiting for fork here
//left and right = the number of sourses
void wait_for_2fork(int no)
{
int left = no;
int right = (no + ) % ;
//system defined struct
//"first":the current number of pro
//"second":resourses -1:wait cannot use;+1:can use
//"thired":?
struct sembuf buf[] =
{
{left, -, },
{right, -, }
};
//semop do wait or signal (p/v)
//"first": the number of share memory pro
//"second":the first point of struct
//"third":the number of signal to complete
semop(semid, buf, );
}
void free_2fork(int no)
{
int left = no;
int right = (no + ) % ;
//system defined struct
//"first":the current number of pro
//"second":resourses -1:wait cannot use;+1:can use
//"thired":?
struct sembuf buf[] =
{
{left, , },
{right, , }
};
semop(semid, buf, );
}
void philosopere(int num)
{
srand(getpid());
for (; ;)
{
//printf("\033[31m Hello\n\033[0m");
//printf("\033[36m Hello\n\033[0m");
//printf("\%d is thinking\n", num);
printf("\033[31m%d is thinking\n\033[0m", num);
sleep(DELAY);
printf("%d pick up two chopsticks\n", num);
printf("\033[36m%d pick up two chopsticks\n\033[0m", num);
wait_for_2fork(num);
//printf("%d is eating\n", num);
printf("\033[34m%d is eating\n\033[0m", num);
sleep(DELAY);
free_2fork(num);
}
}
int main()
{
//use IPC to connect between processes . A new share memory
//semget() return the number of share memory
//new signal key=0 and never change .So not use key
//"first":use IPC_PRIVATE to share memory between relation processes
//"second":(size_t)naxSize
//"third":(int flag)private:666--read and write ; IPC_CREAT creat new memory
semid = semget(IPC_PRIVATE, , IPC_CREAT | );
if (semid == -)
ERR_EXIT("semget");
union semun su;
su.val = ;
for (int i = ; i < ; i++)
{
//creat a new object on "semid"
//use i to depart 5 processes
semctl(semid, i, SETVAL, su);
}
int no = ;
//pid_t (Process ID _ Type) Just like int
pid_t pid;
for (int i = ; i < ; i++)
{
//use fork() to make a copy of father process named with child pro
//father.pid>0 and child.pid=0
//after for loop will exist a father and five childs(0-4)
pid = fork();
if (pid == -)
ERR_EXIT("fork");
if (pid == )
{
no = i;
//break the child process loop to run the philosopere
break;
}
}
philosopere(no);
return ;
}

操作系统课程设计--Linux平台哲学家问题的更多相关文章

  1. Bryce1010的操作系统课程设计

    https://download.csdn.net/download/fire_to_cheat_/10221003 上面是课程设计的代码,下载需要一些积分. 1.作业调度 2.磁盘调度 常见的磁盘调 ...

  2. Perl Tk在IC设计中的应用、Windows、Linux平台下的安装-各种错误的摸索解决

    本文转自:自己的微信公众号<集成电路设计及EDA教程> <Perl Tk在IC设计中的应用.Windows.Linux平台下的安装-各种错误的摸索解决> Perl在IC设计中有 ...

  3. 计算机课程设计-校园二手书交易系统java二手交易平台代码ssm二手商城购物平台跳蚤市场

    计算机课程设计-校园二手书交易系统java二手交易平台代码ssm二手商城购物平台跳蚤市场 注意:该项目只展示部分功能,如需了解,评论区咨询即可. 1.开发环境 开发语言:Java 后台框架:SSM(S ...

  4. C 语言学习的第 05 课:了解课程配套的平台

    在此之前,已经同授课老师沟通,确认课程的配套平台是Coding.net.对于大多数(甚至是全部)同学来说,这个平台应该是极其陌生的.不过不用担心,且还是娓娓道来. 定义:Coding.net是一个集代 ...

  5. 嵌入式系统及应用课程设计——基于STM32的温湿度监测系统

    大三上学期期末总结,嗯,没错上学期,写在新学期开始,hhh. 上学期学了一门嵌入式系统及应用的课程,期末的课程设计题目是基于STM32的温湿度监测系统. 记得刚开始做课程设计的时候,听说先设计画出原理 ...

  6. 《基于Arm实验箱的国密算法应用》课程设计 结题报告

    <基于Arm实验箱的国密算法应用>课程设计 结题报告 小组成员姓名:20155206赵飞 20155220吴思其 20155234昝昕明 指导教师:娄嘉鹏 设计方案 题目要求:基于Arm实 ...

  7. 《基于Cortex-M4的ucOS-III的应用》课程设计 结题报告

    <基于Cortex-M4的ucOS-III的应用>课程设计 结题报告 小组成员姓名:20155211 解雪莹 20155217 杨笛 20155227 辜彦霖 指导教师:娄嘉鹏 一.设计方 ...

  8. 20155338课程设计个人报告——基于ARM实验箱的Android交友软件的设计与实现

    课程设计个人报告--基于ARM实验箱的Android交友软件的设计与实现 个人贡献 实验环境的搭建 代码调试 在电脑上成功运行 研究程序代码撰写小组报告 一.实验环境 1.Eclipse软件开发环境: ...

  9. 转:基于 linux 平台的 libpcap 源代码分析

    libpcap 是 unix/linux 平台下的网络数据包捕获函数包,大多数网络监控软件都以它为基础.Libpcap 可以在绝大多数类 unix 平台下工作,本文分析了 libpcap 在 linu ...

随机推荐

  1. Docker 简介

    1.什么是Docker Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux 机器上.使用Docker可以让每个应用彼此相 ...

  2. tkinter事件机制

    一.tkinter.Event tkinter的事件机制跟js是一样的,也是只有一个Event类,这个类包罗万象,集成了键盘事件,鼠标事件,包含各种参数. 不像java swing那种强类型事件,sw ...

  3. oracle日常——修改用户密码

    修改密码时,先进入sqlplus的sql命令状态(键入用户名密码之后),命令如下: alter user cnp2 identified by cnp3; --即将用户cnp2的密码修改为cnp3 格 ...

  4. 如何有效地解决ie7,IE8不支持document.getElmentsByClassName的问题

    1.复制此代码到你js代码的最前面即可   if(!document.getElementsByClassName){ document.getElementsByClassName = functi ...

  5. 递推 hdu 2064

    z[n] n个盘子从1到3次数 先想2个的时候  1->2 2->3  1->2 3->2 2->1 2->3 1->2 2->3 显然 要先把上面n- ...

  6. python基础补漏-02-collection

    collection系列 [1]计数器 Counter import collections res = collections.Counter("34234sdfgs45tsaf1&quo ...

  7. bzoj2243

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6753  Solved: 2496[Submit][Status ...

  8. Banner中利用Jquery隐藏显示下方DIV块

    实现方式1: <!DOCTYPE html><html><head>    <meta charset="UTF-8">    &l ...

  9. C#调用百度高精度IP定位API通过IP获取地址

    API首页:http://lbsyun.baidu.com/index.php?title=webapi/high-acc-ip 1.申请百度账号,创建应用,获取密钥(AK) http://lbsyu ...

  10. 移动端阻止body滚动

    一些移动设备有缺省的touchmove行为,比如说经典的iOS overscroll效果,当滚动超出了内容的界限时就引发视图反弹 阻止滚动: css: body{ height:100%; overf ...