山东大学linux实验报告,山东大学操作系统实验四

一.实验内容:

抽烟者问题。假设一个系统中有三个抽烟者进程,每个抽烟者不断地卷烟并抽烟。抽烟者卷起并抽掉一颗烟需要有三种材料:烟草、纸和胶水。一个抽烟者有烟草,一个有纸,另一个有胶水。系统中还有两个供应者进程,它们无限地供应所有三种材料,但每次仅轮流提供三种材料中的两种。得到缺失的两种材料的抽烟者在卷起并抽掉一颗烟后会发信号通知供应者,让它继续提供另外的两种材料。这一过程重复进行。 请用以上介绍的IPC同步机制编程,实现该问题要求的功能。

二.实验思路:

1.生产者要能提供三种组合的原料:烟草,纸(SP),烟草,胶水(SG),或是纸和胶水(PG),这就需要一个随机数,来决定提供哪种组合的原料。因为需要两个供应者,所以要两个生产者,两个生产者生产的内容一样,决定通过父子进程来实现。因为父子进程同时向一个临界区里写东西,所以加上互斥。并且生产者能发送三种信号来唤醒不同的消费者。

2.需要三个消费者分别消费不同的内容,通过父进程创建两个子进程来实现,父进程和两个子进程分别执行不同的内容,这个和实验一的内容很相似。三个进程在取东西对临界区进行修改的时候要互斥。

3.因为开始时没有资源,所以将唤醒消费者的三个信号的信号量初始值都设为0,因为生产者一次仅供应一个消费者,所以将消费者唤醒生产者的那个信号量初始值设为1。控制互斥的两个信号量pmtx和cmtx都设为1。

代码如下:

ipc.h:

#include#include#include#include#include#include#include#define BUFSZ256

int get_ipc_id(char*proc_file,key_t key);

char *set_shm(key_t shm_key,int shm_num,int shm_flag);

int set_msq(key_t msq_key,int msq_flag);

int set_sem(key_t sem_key,int sem_val,int sem_flag);

int down(int sem_id);

int up(int sem_id);

typedef union semuns{

int val;

}Sem_uns;

typedef struct msgbuf{

long mtype;

char mtext[1];

}Msg_buf;

key_t buff_key;

int buff_num;

char *buff_ptr;

key_t pput_key;

int pput_num;

int *pput_ptr;

key_t cget_key;

int cget_num;

int *cget_ptr;

//producer semaphore

key_t prod_key;

key_t pmtx_key;

int prod_sem;

int pmtx_sem;

//consumer semaphore

key_t c_PG_key;

key_t c_SG_key;

key_t c_SP_key;

key_t cmtx_key;

int c_PG_sem;

int c_SG_sem;

int c_SP_sem;

int cmtx_sem;

int sem_val;

int sem_flg;

int shm_flg;

ipc.c:

#include "ipc.h"

int get_ipc_id(char *proc_file,key_t key)

{

FILE *pf;

int i,j;

char line[BUFSZ],colum[BUFSZ];

if((pf=fopen(proc_file,"r"))==NULL){

perror("Proc file not open.");

exit(EXIT_FAILURE);

}

fgets(line,BUFSZ,pf);

while(!feof(pf)){

i=j=0;

fgets(line,BUFSZ,pf);

while(line[i]==' ') i++;

while(line[i]!=' ') colum[j++]=line[i++];

colum[j]='\0';

if(atoi(colum)!=key) continue;

j=0;

while(line[i]==' ') i++;

while(line[i]!=' ') colum[j++]=line[i++];

colum[j]='\0';

i=atoi(colum);

fclose(pf);

return i;

}

fclose(pf);

return -1;

}

int down(int sem_id)

{

struct sembuf buf;

buf.sem_op=-1;

buf.sem_num=0;

buf.sem_flg=SEM_UNDO;

if((semop(sem_id,&buf,1))<0){

perror("down error");

exit(EXIT_FAILURE);

}

return EXIT_SUCCESS;

}

int up(int sem_id)

{

struct sembuf buf;

buf.sem_op=1;

buf.sem_num=0;

buf.sem_flg=SEM_UNDO;

if((semop(sem_id,&buf,1))<0){

perror("up error");

exit(EXIT_FAILURE);

}

return EXIT_SUCCESS;

}

int set_sem(key_t sem_key,int sem_val,int sem_flg){

int sem_id;

Sem_uns sem_arg;

if((sem_id=get_ipc_id("/proc/sysvipc/sem",sem_key))<0)

{

if((sem_id=semget(sem_key,1,sem_flg))<0)

{

perror("semaphore create error");

exit(EXIT_FAILURE);

}

sem_arg.val=sem_val;

if(semctl(sem_id,0,SETVAL,sem_arg)<0)

{

perror("semaphore set error");

exit(EXIT_FAILURE);

}

}

return sem_id;

}

char*set_shm(key_t shm_key,int shm_num,int shm_flg)

{

int i,shm_id;

char*shm_buf;

if((shm_id=get_ipc_id("/proc/sysvipc/shm",shm_key))<0)

{

if((shm_id=shmget(shm_key,shm_num,shm_flg))<0)

{

perror("shareMemory set error");

exit(EXIT_FAILURE);

}

if((shm_buf=(char*)shmat(shm_id,0,0))producer.c:

#include"ipc.h"

int main(int argc,char*argv[]){

int rate;

if(argv[1]!=NULL) rate=atoi(argv[1]);

else rate=3;

buff_key=101;

buff_num=8;

pput_key=102;

pput_num=1;

shm_flg=IPC_CREAT|0644;

buff_ptr=(char*)set_shm(buff_key,buff_num,shm_flg);

pput_ptr=(int*)set_shm(pput_key,pput_num,shm_flg);

prod_key=201;

pmtx_key=202;

c_PG_key=301;

c_SP_key=302;

c_SG_key=303;

sem_flg=IPC_CREAT|0644;

sem_val=1;

prod_sem=set_sem(prod_key,sem_val,sem_flg);

sem_val=0;

c_PG_sem=set_sem(c_PG_key,sem_val,sem_flg);

c_SG_sem=set_sem(c_SG_key,sem_val,sem_flg);

c_SP_sem=set_sem(c_SP_key,sem_val,sem_flg);

sem_val=1;

pmtx_sem=set_sem(pmtx_key,sem_val,sem_flg);

int pid;

pid=fork();

if(pid==0){

while(1){

int r=rand()%3;

if(r==0){

down(prod_sem);

down(pmtx_sem);

buff_ptr[*pput_ptr+1]='P';

buff_ptr[*pput_ptr+2]='G';

sleep(rate);

printf("%d渚涘簲鍟嗘彁渚涳細绾?c,鑳舵按%c\n",getpid(),buff_ptr[*pput_ptr+1],buff_ptr[*pput_ptr]+2);

up(pmtx_sem);

up(c_PG_sem);}

else if(r==1){

down(prod_sem);

down(pmtx_sem);

buff_ptr[*pput_ptr]='S';

buff_ptr[*pput_ptr+2]='G';

sleep(rate);

printf("%d渚涘簲鍟嗘彁渚涳細鐑?c,鑳舵按%c\n",getpid(),buff_ptr[*pput_ptr],buff_ptr[*pput_ptr]+2);

up(pmtx_sem);

up(c_SG_sem);

}

else if(r==2){

down(prod_sem);

down(pmtx_sem);

buff_ptr[*pput_ptr]='S';

buff_ptr[*pput_ptr+1]='P';

sleep(rate);

printf("%d渚涘簲鍟嗘彁渚涳細鐑?c,绾?c\n",getpid(),buff_ptr[*pput_ptr],buff_ptr[*pput_ptr]+1);

up(pmtx_sem);

up(c_SP_sem);}}

}else{

while(1){

int r=rand()%3;

if(r==0){

down(prod_sem);

down(pmtx_sem);

buff_ptr[*pput_ptr+1]='P';

buff_ptr[*pput_ptr+2]='G';

sleep(rate);

printf("%d渚涘簲鍟嗘彁渚涳細绾?c,鑳舵按%c\n",getpid(),buff_ptr[*pput_ptr+1],buff_ptr[*pput_ptr]+2);

up(pmtx_sem);

up(c_PG_sem);}

else if(r==1){

down(prod_sem);

down(pmtx_sem);

buff_ptr[*pput_ptr]='S';

buff_ptr[*pput_ptr+2]='G';

sleep(rate);

printf("%d渚涘簲鍟嗘彁渚涳細鐑?c,鑳舵按%c\n",getpid(),buff_ptr[*pput_ptr],buff_ptr[*pput_ptr]+2);

up(pmtx_sem);

up(c_SG_sem);

}

else if(r==2){

down(prod_sem);

down(pmtx_sem);

buff_ptr[*pput_ptr]='S';

buff_ptr[*pput_ptr+1]='P';

sleep(rate);

printf("%d渚涘簲鍟嗘彁渚涳細鐑?c,绾?c\n",getpid(),buff_ptr[*pput_ptr],buff_ptr[*pput_ptr]+1);

up(pmtx_sem);

up(c_SP_sem);}}

}

return EXIT_SUCCESS;

}

consumer.c:

#include"ipc.h"

int main(int argc,char*argv[]){

int rate;

if(argv[1]!=NULL) rate=atoi(argv[1]);

else rate=3;

buff_key=101;

buff_num=3;

cget_key=103;

cget_num=1;

shm_flg=IPC_CREAT|0644;

buff_ptr=(char*)set_shm(buff_key,buff_num,shm_flg);

cget_ptr=(int*)set_shm(cget_key,cget_num,shm_flg);

prod_key=201;

pmtx_key=202;

c_PG_key=301;

c_SP_key=302;

c_SG_key=303;

sem_flg=IPC_CREAT|0644;

sem_val=1;

prod_sem=set_sem(prod_key,sem_val,sem_flg);

sem_val=0;

c_PG_sem=set_sem(c_PG_key,sem_val,sem_flg);

c_SG_sem=set_sem(c_SG_key,sem_val,sem_flg);

c_SP_sem=set_sem(c_SP_key,sem_val,sem_flg);

sem_val=1;

cmtx_sem=set_sem(cmtx_key,sem_val,sem_flg);

int pid1,pid2;

if((pid1=fork())==0){

while(1){

down(c_PG_sem);

down(cmtx_sem);

sleep(rate);

printf("%d鏈夌儫鑽夌殑鍚哥儫鑰呬粠渚涘簲鍟嗗緱鍒扮焊%c,鑳舵按%c寮€濮嬪惛鐑焅n",getpid(),buff_ptr[*cget_ptr+1],buff_ptr[*cget_ptr]+2);

up(cmtx_sem);

up(prod_sem);}}

else if((pid2=fork())==0){

while(1){

down(c_SG_sem);

down(cmtx_sem);

sleep(rate);

printf("%d鏈夌焊鐨勫惛鐑熻€呬粠渚涘簲鍟嗗緱鍒扮儫%c,鑳舵按%c寮€濮嬪惛鐑焅n",getpid(),buff_ptr[*cget_ptr],buff_ptr[*cget_ptr]+2);

up(cmtx_sem);

up(prod_sem);}}

else{

while(1){

down(c_SP_sem);

down(cmtx_sem);

sleep(rate);

printf("%d鏈夎兌姘寸殑鍚哥儫鑰呬粠渚涘簲鍟嗗緱鍒扮儫%c,绾?c寮€濮嬪惛鐑焅n",getpid(),buff_ptr[*cget_ptr],buff_ptr[*cget_ptr]+1);

up(cmtx_sem);

up(prod_sem);}}

return EXIT_SUCCESS;

}

在linux系统中写的中文拿到windows系统上是乱码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/560610.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通过CDN引用jQuery库+jQuery的使用+网页实现计算器的功能

jQuery是什么&#xff1f;有什么用&#xff1f; jQuery是javascript库&#xff0c;其实就是一堆的js函数&#xff0c;方便我们来调用&#xff0c;提高我们的开发效率 免费开源&#xff0c;支持主流浏览器&#xff0c;简化选取网页元素的语法&#xff0c;简易的读取设置元素的…

amd cpu排行_最新AMD CPU排行出炉 E6版3000+夺魁

据消费调研中心ZDC统计结果显示&#xff0c;2006年3月最受用户关注的前十款AMD CPU中&#xff0c;Athlon64和Sempron两大系列产品平分秋色&#xff0c;各有五款产品入围。具体产品排行如下图所示。(图)2006年3月最受用户关注的前十款AMD CPU排名产品名称报价L2缓存(KB)插槽类型…

java异常及错误处理大纲

文章目录1.异常处理2. 自定义异常3. 断言及程序的测试4. 程序的调试1.异常处理 异常&#xff08;exception ) 又称为例外、差错、违例 对应着Java运行错误处理机制 基本写法 try{ 语句组 }catch(Exception ex){ 异常处理语句组&#xff1b; }import java.io.*; public cla…

linux dev alloc name,深入理解Linux网络技术内幕-设备注册和初始化(二)

NIC注册和注销的通用架构Linux系统中NIC网络设备驱动程序利用网络代码进行注册和注销有其通用的架构&#xff0c;这里以PCI Ethernet NIC为例&#xff0c;其他设备类型只是所以函数名称和调用方式不同&#xff0c;主要依据于设备总线提供的接口。其中(a)为设备注册的大致流程图…

外贸常用术语_外贸中常用的会计术语及付款方式术语 | 会计英语

点击上面“财经英语”关注公众号&#xff01;点击下面小程序加入: 学习圈财经英语 学习圈 预付现金 Cash advance 凭提货单支付现金 Cash against Bill of Lading (B/L) 凭单据付现款||凭装货单付现款 Cash against Documents 现金结存||现金差额 Cash balance 现收现付制||现金…

c语言中block做函数参数,c语言中的block

//block块(数据类型) 封装的一段具有特定功能的代码段//函数有函数名&#xff0c;block没有名字&#xff0c;也可以叫做匿名函数&#xff1b;函数不能做参数传递&#xff0c;block可以作为参数传递&#xff1b;//形式&#xff1a;/* 返回值类型,(^ block变量名)(参数列表)&…

python 多维list 排序_一行代码的优雅| Python列表生成式

欢迎回来&#xff0c;上一周我们整理了基础课中三大结构有关内容的具体应用及案例。可以通过以下几篇推文进行回溯&#xff1a;Python语言基础50课我的Python - 100天笔记 |D1-D7我的Python - 100天笔记 |D8-D14列表是Python中非常常见的数据结构&#xff0c;在基础课中也占了不…

c语言高斯白序列x,C语言程序设计程设计指导书(晓庄).doc

C语言程序设计程设计指导书(晓庄)C语言程序设计课程设计任务书南京晓庄学院数学与信息技术学院2011-9-20一、C语言程序设计课程设计的目的说明1)复习巩固C语言的基础知识&#xff0c;进一步加深对C语言编程的理解和掌握&#xff1b;2)利用所学知识&#xff0c;理论和实际结合锻…

arduino智能风扇系统

研究方法与思路&#xff1a; 我们小组一开始找的是一个别人做好的项目&#xff0c;按键控制风扇挡位&#xff0c;不同挡位对应不同LED灯。但是实现过程中存在bug。而且仅仅通过按键控制风扇着实有局限性&#xff0c;因此我觉定用串口控制风扇开关的模式&#xff0c;输入1&…

verilog 生成块_如何高效的编写Verilog——终极版

为了高效的编写Verilog&#xff0c;通常有些编辑器插件可以自动生成代码&#xff0c;比如自动端口定义&#xff0c;自动连线&#xff0c;自动实例化等等。公司的环境有很好用的自动化插件&#xff0c;想给自己的电脑也整个怎么做。比如Emacs中有个插件叫verilog-mode。但是博主…

arduino串口输入改变模式模块

最新更新: 当时太嫩&#xff0c;做这个不知道arduino还有中断的方法&#xff0c;利用中断的方法可以比下面这种循环判断的方法更简单。 最近做了不少arduino智能系统&#xff0c;我发现在与用户交互的过程中&#xff0c;经常用到&#xff1a;通过在串口输入不同的值达到手动控…

android悬浮动态权限,Android 获取判断是否有悬浮窗权限的方法

现在很多应用都会用到悬浮窗&#xff0c;很多国产rom把悬浮窗权限加入控制了&#xff0c;你就需要判断是否有悬浮窗权限&#xff0c;然后做对应操作。Android 原生有自带权限管理的&#xff0c;只是被隐藏了。看android源码在android.app下就有个AppOpsManager类。类说明如下&a…

剩余 大小 查看内存_JVM的内存分配策略以及进入分代的条件

JVM的参数和知识点太多啦&#xff0c;记录下来&#xff0c;供自己随时回顾。java对象什么时候进入年轻代&#xff08;新生代&#xff09;&#xff1f;java对象什么时候进入老年代&#xff1f;对象优先在Eden分配大对象直接进入老年代空间分配担保机制java对象什么时候进入年轻代…

Arduino的串口结束符及串口缓冲区

文章目录1.深入理解缓冲区和Serial.available()&#xff1a;2.深入理解串口结束符3.验证结论&#xff1a;1.深入理解缓冲区和Serial.available()&#xff1a; 运行下面的代码&#xff0c;我发现如果不在串口输入任何数字&#xff0c;就会一直显示“no”&#xff0c;输入一个数…

android 圆角边框边框渐变,支持边框、圆角、渐变色、透明度的GradientButton

最近在项目中发现好多Button背景颜色相同&#xff0c;但圆角大小不等的Button&#xff0c;这样就得写一大堆的shape或者selector&#xff0c;不便于管理及后期维护&#xff0c;于是乎变想能不能写一个支持边框、圆角、渐变色、透明度的万用Button呢。为了能够兼容button自带的属…

(斜率,点和线段)zzuli1196数星星(二)

题目描述 一天&#xff0c;小明坐在院子里数星星&#xff0c;Gardon就出了个难题给他&#xff0c;让他数数天上的星星最多有多少个是在同一条直线上的。天上的星星太多了&#xff0c;小明马上就看花了眼&#xff0c;你能写个程序来帮他计算么&#xff1f; 输入 首先输入一个整…

鸿蒙ide如何运行,深入浅析华为鸿蒙IDE安装与Hello World

一、系统安装1. 到官网下载HUAWEI DevEco Studio2. 安装二、创建项目创建项目目前还没有手机选项&#xff0c;所以我先选择一个电视&#xff1a;IDE的环境看起来和idea差不多&#xff0c;应该比较容易上手。从“关于”里也可以看到&#xff0c;确实是基于IDEA开源版本开发的。我…

springboot 上传文件解析入库_SpringBoot + easyexcel + WebUploader 实现文件上传并解析

1. WebUploader的使用&#xff0c;引入css和js&#xff0c;css其实没什么用&#xff1a;2. 定义上传框&#xff1a;选择文件开始上传3.相关jquery&#xff1a;// 文件上传jQuery(function() {var $ jQuery,$list $(#thelist),$btn $(#ctlBtn),state pending,uploader;uploa…

中快捷搜索_同事用1分钟,我用半小时,原来是因为这8个Word快捷键,秒杀一切办公技巧...

同事用1分钟&#xff0c;我用半小时&#xff0c;这8个Word快捷键&#xff0c;秒杀一切办公技巧​mp.weixin.qq.com文&#xff5c;王羽卒今天给小伙伴们分享几个实用又有效的快捷键&#xff0c;帮助快速完成工作&#xff0c;同事用了半小时&#xff0c;你1分钟就能解决哟&#x…

动态规划理论基础

(采用维特根斯坦的表述方式) 1.达成目的过程可以由不同阶段组成 2.阶段由达成目的的条件确定 (注&#xff1a;规定每一次走一步&#xff0c;第一步就是一个阶段) 3.每个阶段由不同的状态组成 4.状态是阶段中可能面临的所有情况 (注&#xff1a;第一步落脚点可能有多个&am…