读者写者问题-操作系统实验报告 (1)

读者写者问题-操作系统实验报告 (1)
读者写者问题-操作系统实验报告 (1)

实验内容

1、定义一个数据缓存buffer 及用于实现同步互斥的信号量。

2、定义一个读者函数:

● 当有写者在占用buffer 时,读者应该等待,直到写者不再使用该buffer 。

● 当有其他读者在占用buffer 时,读者可对buffer 进行读取操作。

● 当buffer 中有数据时,则从其中读取一个数据,并显示然后退出。

● 当buffer 中没有数据时,应等待,直到buffer 中有数据可读。

3、定义一个写者函数

● 当有读者在占用buffer 时,写者应该等待,直到所有的读者都退出为止。

● 当有其他写者占用buffer 时,该写者应该等待,直到占用buffer 的写者退出为止。

● 当buffer 有空闲时,写者应该在buffer 中写入一个数据并退出。

● 当buffer 满时,写者应该等待,直到buffer 有空闲为止。

4、定义主函数,在其中可以任意创建读者与写者。

● 可根据用户输入创建读者或写者进程(线程)。

5、用户界面

2. 写者: 开始

读出的内容:

1. 读者: 开始

结束 2

1

读者队列等待

结束

写出的内容: Hello world ! 结束

实验当堂所要完成事情列表:

1.调试程序使其在读者优先模式下可以运行并且能实现基本的功能得出正确的

结果:能够实现读写互斥,写写互斥,读读不互斥,一个进程结束能够唤醒等

待队列中的进程(先读者队列后写着队列)

2.根据实验要求完善功能:由用户决定写者向缓冲区中写入的内容,读者能够读

出并显示出来;当缓冲区中没有数据时,读者要等待,直到缓冲区中有数据才

能读

3.根据“读者优先”加以改变,增加一个“写者优先”模式,并且由用户来选择

模式

源代码:

#include

#include

int rcount=0;//正在读的读者数量

int wcount=0;//写者队列中等待写操作的写者数量

int read_id=0;//读进程号

int write_id=0;//写进程号

int w=1;//读写互斥信号量

char temp[300] = {'\0'};

int choice; //用户选择读者优先OR写者优先

int sign; //标识temp空的信号量 0表示temp空

void WFwakeup();

void RFwakeup();

struct rqueue{//读者等待队列

int readers[200];

int index;

}rq;

struct wqueue{//写者等待队列

int writers[200];

int index;

}wq;

/*void first(){ //初始化

int i;

rq.index = 0;

wq.index = 0;

for(i = 0;i<20;i++){

rq.readers[i] = 0;

wq.writers[i] = 0;

}

}*/

//*******************************************读进程读操作

void read(){

int i = 0;

read_id++;

if(rcount == 0){//当前没有读进程在读可能有写进程在写可能CPU空闲

if(w==1) {//如果CPU空闲,读者拿到CPU

w--;// 相当于一个P操作

rcount++;

if(temp[0] == '\0'){

sign = 0;

if(choice == 1){

rq.readers[rq.index++]=read_id;//将读者进程加入等待队列

RFwakeup();

return;

}

else{

rq.readers[rq.index++]=read_id;//将读者进程加入等待队列

WFwakeup();

return;

}

}//if

printf("读者%d正在读\n",read_id);

for(i = 0;i < 300;i++){//读取temp内容即写者写的内容

if(temp[i] == '\0'){

printf("\n");

return;

}//if

printf("%c",temp[i]);

}//for

}//if

else{//写者线程正在执行

printf("!有写者在写不能读!\n");

rq.readers[rq.index++]=read_id;//将读者进程加入等待队列

}//else

}//if

else{//rcount !=1 则知道当前已经有读者在读,读读不互斥,则这个读者可以直接进来了读

printf("读者%d正在读\n",read_id);

for(i = 0;i < 300;i++){

if(temp[i] == '\0'){

printf("\n");

return;

}

printf("%c",temp[i]);

}//for

}//else

}

//***************************写进程写操作

void write(){

write_id++;

if(w == 0){

if(rcount != 0 ){//有读者进程在执行

printf("!有读者在读不能写!\n");

wq.writers[wq.index++]=write_id;//将写者进程加入等待队列

wcount++;

return;

}

if(rcount == 0 ){//rcount == 0则当前无读者,但w = 0,所以有写者在写

printf("!有写者在写不能写!\n");

wq.writers[wq.index++]=write_id;//将写者进程加入等待队列

wcount++;

return;

}

}

if(w == 1){

w--;

printf("写者%d正在写\n请输入要写的内容",write_id);

scanf("%s",temp);

//while

}//if

}

//************************读者优先时唤醒进程

void RFwakeup(){

int i = 0;

int j = 0;

int m,n;

m = rq.index;

// n = wq.index;

if(rcount == 0){//当前无读进程,是写者在写 --》停止运行写进程

bool reader_wait=false;

w=1;

printf("写者已经写完\n");

sign = 1;//temp中已经有内容要置1

for(i=0;i<=m;i++){// i ndex为当前读者队列中的等待进程数

if(rq.readers[i]!=0){

reader_wait=true; //确实有读者在等待

printf("等待的读者%d正在读\n",rq.readers[i]);

w = 0;

for(j = 0;j < 300;j++){

if(temp[j] == '\0'){

printf("\n");

break;

}//if

printf("%c",temp[j]);

}//for

rq.readers[i]=0;

rcount++;

rq.index--;

}//if

}//for

if(!reader_wait){//没有读者等待,看是否有写者等待

for(int i=0;i<=wq.index;i++){//检查写者等待队列

if(wq.writers[i]!=0){

w = 0;

printf("等待的写者%d正在写\n请输入要写入的内容",wq.writers[i]);

scanf("%s",temp);

wq.writers[i]=0;

wcount--;

break;

}//if

}//for

}//if

// return;

}//if

else{//rcount != 0读者正在读,stop读此时若有等待必为写者

rcount=0;

w = 1;

if(sign == 0){

printf("缓冲区空等待写者\n");

return;

}

else{

printf("读者已经读完\n");

for(int i=0;i<=wq.index;i++){// 检查写者等待队列

if(wq.writers[i]!=0){

w = 0;

printf("等待的写者%d正在写\n请输入要写入的内容",wq.writers[i]);

scanf("%s",temp);

wq.writers[i]=0;

wcount--;

break;

}//if

}//for

}

}//else

}

//******************************************写者优先唤醒

void WFwakeup(){

int i = 0;

int j = 0;

int m,n;

m = rq.index;

//n = wq.index;

if(rcount == 0){//当前无读进程,是写者在写 --》停止运行写进程

bool writer_wait=false;

w=1;

printf("写者已经写完\n");

sign = 1;//temp中已经有内容要置1

for(i=0;i<=wq.index;i++){// index为当前写者队列中的等待进程数

if(wq.writers[i]!=0){

writer_wait=true; //确实有写者在等待

printf("等待的写者%d正在写\n 请输入要写的内容

\n",wq.writers[i]);

w = 0;

scanf("%s",temp);

wq.writers[i]=0;

wcount--;

break;

}

}

if(!writer_wait){//没有xie者等待,看是否有du者等待for(int i=0;i<=m;i++){//检查写者等待队列

if(rq.readers[i]!=0){

w = 0;

printf("等待的读者%d正在读\n",rq.readers[i]);

for(j = 0;j < 300;j++){

if(temp[j] == '\0'){

printf("\n");

rq.index--;

break;

}//if

printf("%c",temp[j]);

}//for

rq.readers[i]=0;

rcount++;

}//if

}//for

}//if

// return;

}//if

else{//rcount != 0读者正在读,stop读此时若有等待必为写者

rcount=0;

w = 1;

printf("读者已经读完\n");

for(int i=0;i<=wq.index;i++){// 检查写者等待队列

if(wq.writers[i]!=0){

w = 0;

printf("等待的写者%d正在写\n请输入要写入的内容",wq.writers[i]);

scanf("%s",temp);

wq.writers[i]=0;

wcount--;

break;

}//if

}//for

}

}

void menu1(){

char i;

printf(" 1-创建读者进程\n 2-创建写者进程\n 3-结束当前执行的进程\n 4-退出程序\n");

printf("*******************************************\n");

do{

printf("当前队列中有读者: %d个写者: %d个

\n",rq.index,wcount);

printf("*******************************************\n");

printf(" ----->");

scanf("%s",&i);

switch(i){

case '1':

read();

break;

case '2':

write();

break;

case '3':

RFwakeup();

break;

case '4':

exit(0);

default:

printf("输入错误请重新输入\n");

}

}while(true);

}

void menu2(){

char i;

printf(" 1-创建读者进程\n 2-创建写者进程\n 3-结束当前执行的进程\n 4-退出程序\n");

printf("*******************************************\n");

do{

printf("当前队列中有读者: %d个写者: %d个

\n",rq.index,wcount);

printf("*******************************************\n");

printf(" ----->");

scanf("%s",&i);

switch(i){

case '1':

read();

break;

case '2':

write();

break;

case '3':

WFwakeup();

break;

case '4':

exit(0);

default:

printf("输入错误请重新输入\n");

}

}while(true);

}

void main(){

printf("*************************************************** ***********************\n");

printf(" 20092104实验一\n 1.读者优先\n 2.写者优先\n");

scanf("%d",&choice);

while(1){

if(choice == 1)

menu1();

if(choice == 2)

menu2();

if(choice != 1 && choice != 2){

printf("输入错误请重新输入\n");

scanf("%d",&choice);

}

}

}

实验流程图:

N

Y

开始

读者优先

写者优先

读操作

写操作

是否有读者在读

进行读操作

Y

CPU 是否空闲

缓冲区是否为空

有写者 读者入队

N

Y 入读者等待队列

调用读者优先唤醒

读操作

N

是否有读者在读

有读者 写者入队

Y

N

Cpu 是否空闲

进行写操作

有写者,写操作入队

Y

N

退出

结束

读者优先唤醒

写者优先唤醒

核心部分设计思路:

读者优先唤醒

当前有无读者在读

有无读者等待

N

有无写者等待

N 读者出队进行读操作直到读者队空

Y

进行写操作 Y

N 返回

Y

缓冲区是否为空

Y

N

写者优先唤醒

当前有无读者在读

有无写者等待

N

有无读者等待

N 写者出队进行写操作直到写者队空

Y

进行读操作直到读者队列为空

Y

N 返回

Y

N

写者队列是否为空

进行写操作直到写者队列为空

Y

有读者说明若有等待必为写者

分别用两个队列来存放等待的读者进程和写者进程,一个进程结束后就要将因他阻塞的进程唤醒,如果是读者优先,则先检查读者进程,如果发现读者进程不为空,就进行读操作,直到读者进程为空,才进行写操作;同理,如果是写者优先,则先检查写进程,如果发现写者进程不为空,就进行写操作,直到写者进程为空,才进行读操作。

读写互斥:只有当互斥信号量W =1并且当前读者数为0时,才可以进行写操作,对于读进程,W =1且当前读者数为0时,第一个读进程进行读操作,当当前读者数大于0时,不用判断互斥信号量W而直接进行读操作。对缓冲区为空的情况,如果缓冲区为空时进行读操作,则会设置一个信号量标志缓冲区为空SIGN =0,不可以进行读操作,释放出CPU,调用唤醒函数唤醒写进程,此时会将此进程放入读者进程等待队列中等待写者来写数据再进行读操作,写者写完数据,缓冲区不空时,将标志置为缓冲区不空SIGN =1。

编译过程中遇到的问题:

1.编译过程中出现的一个很大的错误就是在构造队列的时候给变量

INDEX赋值了,系统提示错误

解决:取消赋值,编写了一个初始化函数进行初始化,后来发现不初始化也没用什么问题,就注释掉了。

2.刚开始还会出现一些括号不匹配的错误,在后来的程序完善过程中,

尽量给后括号做一个注释进行标识。

运行过程中遇到的问题:

1.不能接受非法字符,如果输入非法字符就会进入死循环,但是在SWITCH

外明明有检查语句。

解决:通过单步跟踪,发现检查语句并没有起到作用,于是调整了一下结构,将检查语句放到SWITCH里,既起到了检查的作用,同时也减少了代码量。

2.在读者进行读取数据时,总是会在读取完写者写的内容的后面出现一

个小A。

解决:也是通过单步跟踪,发现是判空和输出的顺序问题,如果先输出后判空的话,会多进行一次循环,导致输出一个小A,但是现在还是不太明白为什么多输出的是小A。

3.当缓冲区为空的时候创建了N-1个读进程,他们都在等待写进程写数

据,然而等写进程写完数据后,这些读进程并没有进行读取,继续创建读进程,就会发现是读进程N在进行读取。

解决:刚开始是以为参数设置问题,后来仔细一想,发现是没有在调用唤醒函数前没有将读进程放入读者等待队列中,于是在调用唤醒函数前,添加将读者进程放入等待队列的语句。

4.还出现了不少小错误,例如将I,J写错导致读者每次都会读300次用

一个字母,没有设置信号量SIGN导致在缓冲区为空的时候还没有进行读操作就会有“读者已经读完”的错误提示等等。也有一些原则性错误比如在唤醒函数中,读或者写进程结束后,将信号量置1,但是在队列中选择进程进行操作的时候,没有把信号量置0,导致了执行唤醒函数后进程不互斥的问题。开始的程序中还设置了一些意义不大的变量,比较混乱,后来通过画简单的流程图,将意义不大的变量取消,理清了思路,解决了问题。

运行过程中的问题出现的问题比较多,但都不是特别大的问题,通过调试分析都得到了解决。

实验收获与心得:

这次实验耗时比较多,预习的时候并没有准备特别充分,程序还有很多问题,功能也不没有达到老师的要求。实验过程中,一步一步由简到繁,完善程序的同时,问题也出现了不少,通过画简单的流程图,通过单步跟踪,通过分析理解,都得到了解决。程序的缺点就是设置的变量过多,后来经过分析和调试,发现很多都是没有必要的,还让程序更加混乱,条理不清楚,后来去掉了不少。这次实验让我更

加深刻的理解了进程的信号量的概念和应用,在不断出现错误,发现错误,改正错误的过程中,对互斥信号量有了非常深刻的理解。虽然程序的功能还不是很完善,但是自己调试成功的程序就非常有成就感。下次实验我会提前做好充分的预习,争取做的更好。

操作系统实验报告--实验一--进程管理

实验一进程管理 一、目的 进程调度是处理机管理的核心内容。本实验要求编写和调试一个简单的进程调度程序。通过本实验加深理解有关进程控制块、进程队列的概念,并体会和了解进程调度算法的具体实施办法。 二、实验内容及要求 1、设计进程控制块PCB的结构(PCB结构通常包括以下信息:进程名(进程ID)、进程优先数、轮转时间片、进程所占用的CPU时间、进程的状态、当前队列指针等。可根据实验的不同,PCB结构的内容可以作适当的增删)。为了便于处理,程序中的某进程运行时间以时间片为单位计算。各进程的轮转时间数以及进程需运行的时间片数的初始值均由用户给定。 2、系统资源(r1…r w),共有w类,每类数目为r1…r w。随机产生n进程P i(id,s(j,k),t),0<=i<=n,0<=j<=m,0<=k<=dt为总运行时间,在运行过程中,会随机申请新的资源。 3、每个进程可有三个状态(即就绪状态W、运行状态R、等待或阻塞状态B),并假设初始状态为就绪状态。建立进程就绪队列。 4、编制进程调度算法:时间片轮转调度算法 本程序用该算法对n个进程进行调度,进程每执行一次,CPU时间片数加1,进程还需要的时间片数减1。在调度算法中,采用固定时间片(即:每执行一次进程,该进程的执行时间片数为已执行了1个单位),这时,CPU时间片数加1,进程还需要的时间片数减1,并排列到就绪队列的尾上。 三、实验环境 操作系统环境:Windows系统。 编程语言:C#。 四、实验思路和设计 1、程序流程图

2、主要程序代码 //PCB结构体 struct pcb { public int id; //进程ID public int ra; //所需资源A的数量 public int rb; //所需资源B的数量 public int rc; //所需资源C的数量 public int ntime; //所需的时间片个数 public int rtime; //已经运行的时间片个数 public char state; //进程状态,W(等待)、R(运行)、B(阻塞) //public int next; } ArrayList hready = new ArrayList(); ArrayList hblock = new ArrayList(); Random random = new Random(); //ArrayList p = new ArrayList(); int m, n, r, a,a1, b,b1, c,c1, h = 0, i = 1, time1Inteval;//m为要模拟的进程个数,n为初始化进程个数 //r为可随机产生的进程数(r=m-n) //a,b,c分别为A,B,C三类资源的总量 //i为进城计数,i=1…n //h为运行的时间片次数,time1Inteval为时间片大小(毫秒) //对进程进行初始化,建立就绪数组、阻塞数组。 public void input()//对进程进行初始化,建立就绪队列、阻塞队列 { m = int.Parse(textBox4.Text); n = int.Parse(textBox5.Text); a = int.Parse(textBox6.Text); b = int.Parse(textBox7.Text); c = int.Parse(textBox8.Text); a1 = a; b1 = b; c1 = c; r = m - n; time1Inteval = int.Parse(textBox9.Text); timer1.Interval = time1Inteval; for (i = 1; i <= n; i++) { pcb jincheng = new pcb(); jincheng.id = i; jincheng.ra = (random.Next(a) + 1); jincheng.rb = (random.Next(b) + 1); jincheng.rc = (random.Next(c) + 1); jincheng.ntime = (random.Next(1, 5)); jincheng.rtime = 0;

操作系统实验报告一

重庆大学 学生实验报告 实验课程名称操作系统原理 开课实验室DS1501 学院软件学院年级2013专业班软件工程2 班学生姓名胡其友学号20131802 开课时间2015至2016学年第一学期 总成绩 教师签名洪明坚 软件学院制

《操作系统原理》实验报告 开课实验室:年月日学院软件学院年级、专业、班2013级软件工 程2班 姓名胡其友成绩 课程名称操作系统原理 实验项目 名称 指导教师洪明坚 教师 评语教师签名:洪明坚年月日 1.实验目的: ?进入实验环境 –双击expenv/setvars.bat ?检出(checkout)EPOS的源代码 –svn checkout https://www.360docs.net/doc/7e9239611.html,/svn/epos ?编译及运行 –cd epos/app –make run ?清除所有的临时文件 –make clean ?调试 –make debug ?在“Bochs Enhanced Debugger”中,输入“quit”退出调试 –调试指令,请看附录A 2.实验内容: ?编写系统调用“time_t time(time_t *loc)” –功能描述 ?返回从格林尼治时间1970年1月1日午夜起所经过的秒数。如果指针loc 非NULL,则返回值也被填到loc所指向的内存位置 –数据类型time_t其实就是long ?typedef long time_t; 3.实验步骤: ?Kernel space –K1、在machdep.c中,编写系统调用的实现函数“time_t sys_time()”,计算用户秒数。需要用到 ?变量g_startup_time,它记录了EPOS启动时,距离格林尼治时间1970年1午夜的秒数 ?变量g_timer_ticks

嵌入式操作系统实验报告

中南大学信息科学与工程学院实验报告 姓名:安磊 班级:计科0901 学号: 0909090310

指导老师:宋虹

目录 课程设计内容 ----------------------------------- 3 uC/OS操作系统简介 ------------------------------------ 3 uC/OS操作系统的组成 ------------------------------ 3 uC/OS操作系统功能作用 ---------------------------- 4 uC/OS文件系统的建立 ---------------------------- 6 文件系统设计的原则 ------------------------------6 文件系统的层次结构和功能模块 ---------------------6 文件系统的详细设计 -------------------------------- 8 文件系统核心代码 --------------------------------- 9 课程设计感想 ------------------------------------- 11 附录-------------------------------------------------- 12

课程设计内容 在uC/OS操作系统中增加一个简单的文件系统。 要求如下: (1)熟悉并分析uc/os操作系统 (2)设计并实现一个简单的文件系统 (3)可以是存放在内存的虚拟文件系统,也可以是存放在磁盘的实际文件系统 (4)编写测试代码,测试对文件的相关操作:建立,读写等 课程设计目的 操作系统课程主要讲述的内容是多道操作系统的原理与技术,与其它计算机原理、编译原理、汇编语言、计算机网络、程序设计等专业课程关系十分密切。 本课程设计的目的综合应用学生所学知识,建立系统和完整的计算机系统概念,理解和巩固操作系统基本理论、原理和方法,掌握操作系统开发的基本技能。 I.uC/OS操作系统简介 μC/OS-II是一种可移植的,可植入ROM的,可裁剪的,抢占式的,实时多任务操作系统内核。它被广泛应用于微处理器、微控制器和数字信号处理器。 μC/OS 和μC/OS-II 是专门为计算机的嵌入式应用设计的,绝大部分代码是用C语言编写的。CPU 硬件相关部分是用汇编语言编写的、总量约200行的汇编语言部分被压缩到最低限度,为的是便于移植到任何一种其它的CPU 上。用户只要有标准的ANSI 的C交叉编译器,有汇编器、连接器等软件工具,就可以将μC/OS-II嵌入到开发的产品中。μC/OS-II 具有执行效率高、占用空间小、实时性能优良和可扩展性强等特点,最小内核可编译至2KB 。μC/OS-II 已经移植到了几乎所有知名的CPU 上。 严格地说uC/OS-II只是一个实时操作系统内核,它仅仅包含了任务调度,任务管理,时间管理,内存管理和任务间的通信和同步等基本功能。没有提供输入输出管理,文件系统,网络等额外的服务。但由于uC/OS-II良好的可扩展性和源码开放,这些非必须的功能完全 可以由用户自己根据需要分别实现。 uC/OS-II目标是实现一个基于优先级调度的抢占式的实时内核,并在这个内核之上提供最基本的系统服务,如信号量,邮箱,消息队列,内存管理,中断管理等。 uC/OS操作系统的组成 μC/OS-II可以大致分成核心、任务处理、时间处理、任务同步与通信,CPU的移植等5个部分。如下图:

操作系统实验报告4

《操作系统》实验报告 实验序号: 4 实验项目名称:进程控制

Printf(“child Complete”); CloseHandle(pi.hProcess); CloseHandle(pi hThread); ﹜ 修改后: #include #include int main(VOID) { STARTUPINFO si; PROCESS_INFORMA TION pi; ZeroMemory(&si,sizeof(si)); si.cb=sizeof(si); ZeroMemory(&pi,sizeof(pi)); if(!CreateProcess(NULL, "c:\\WINDOWS\\system32\\mspaint.exe", NULL, NULL, FALSE, 0, NULL, NULL, &si,&pi)) { fprintf(stderr,"Creat Process Failed"); return -1; } WaitForSingleObject(pi.hProcess,INFINITE); printf("child Complete"); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } 在“命令提示符”窗口运行CL命令产生可执行程序4-1.exe:C:\ >CL 4-1.cpp

实验任务:写出程序的运行结果。 4.正在运行的进程 (2)、编程二下面给出了一个使用进程和操作系统版本信息应用程序(文件名为4-5.cpp)。它利用进程信息查询的API函数GetProcessVersion()与GetVersionEx()的共同作用。确定运行进程的操作系统版本号。阅读该程序并完成实验任务。 #include #include

请用PV操作解决读者和写者问题

请用PV操作解决读者和写者问题。有两组并发进程:读者和写者,共享一个文件,要求:(1)允许多个读者同时执行读操作(2)在任意写者在完成写操作之前,不允许其他任意的读者和写者工作 3写者预工作,但在它之前已有读者在执行读操作,那么,待现有读者完成读操作后在执行写操作,新的读者和写者均被拒绝。Samapher matex=1/*对文件互斥*/ S1=1/*对Readcount互斥*/ Readcount=0读者记数器。 Reader: Writer: P(S1); P(mutex); Readcount++; Write a file; V(S1); V(mutex); Read a file; P(S1); Readcount--; If(Readcount==0) V(mutex); V(S1); 设由n个缓冲区组成缓冲池,每个缓冲区可以存放一个消息,有两类进程:x个生产者和y 个消费者,且只要缓冲池未满,生产者便可以将消息送入缓冲池,而只要缓冲池未空,消费者就可以取走一个消息。各个进程对缓冲池进行互斥访问,用信号量实现协调过程。要求写出使用的信号量、初值及其作用,并写出生产者进程和消费者进程的处理流程(10分)

某寺庙共有老和尚和小和尚若干人,庙外有一口井,只能容一人打水,庙内有6只水桶和一口缸,缸内最多能装30桶水,每只桶每次只能由一人使用,缸每次只能由一人使用。小和尚负责从庙外的井里打水,老和尚使用缸里的水,老和尚取水的单位是桶。请利用信号量和P、V操作描述老和尚和小和尚的活动。semaphore empty=30; // 表示缸中目前还能装多少桶水,初始时能装30桶水 semaphore full=0; // 表示缸中有多少桶水,初始时缸中没有水 semaphore buckets=6; // 表示有多少只空桶可用,初始时有6只桶可用 semaphore mutex_well=1; // 用于实现对井的互斥操作 semaphore mutex_bigjar=1; // 用于实现对缸的互斥操作 semaphore mutex_buchet=1; // 用于实现对桶的互斥操作,防止多人同时拿同一只桶yongermonk(){ while(1){P(empty); P(buckets); P(mutex_bucket); get a bucket; V(mutex_bucket); go to the well; P(mutex_well); get water; V(mutex_well); go to the temple; P(mutex_bigjar); pure the water into the big jar; V(mutex_bigjar); V(buckets); V(full);}} oldmonk(){ while(1){P(full); P(buckets); P(mutex_bucket); get a bucket; V(mutex_bucket); P(mutex_bigjar); get water; V(mutex_bigjar); V(buckets); V(empty); } }

实时操作系统报告

实时操作系统课程实验报告 专业:通信1001 学号:3100601025 姓名:陈治州 完成时间:2013年6月11日

实验简易电饭煲的模拟 一.实验目的: 掌握在基于嵌入式实时操作系统μC/OS-II的应用中,基于多任务的模式的编程方法。锻炼综合应用多任务机制,任务间的通信机制,内存管理等的能力。 二.实验要求: 1.按“S”开机,系统进入待机状态,时间区域显示当前北京时间,默认模式“煮饭”; 2.按“C”选择模式,即在“煮饭”、“煮粥”和“煮面”模式中循环选择; 3.按“B”开始执行模式命令,“开始”状态选中,时间区域开始倒计时,倒计时完成后进入“保温”状态,同时该状态显示选中,时间区域显示保温时间; 4.按“Q”取消当前工作状态,系统进入待机状态,时间区域显示北京时间,模式为当前模式; 5.按“X”退出系统,时间区域不显示。 6.煮饭时长为30,煮粥时长为50,煮面时长为40. 三.实验设计: 1.设计思路: 以老师所给的五个程序为基础,看懂每个实验之后,对borlandc的操作有了大概的认识,重点以第五个实验Task_EX为框架,利用其中界面显示与按键扫描以及做出相应的响应,对应实现此次实验所需要的功能。 本次实验分为界面显示、按键查询与响应、切换功能、时钟显示与倒计时模块,综合在一起实验所需功能。 2.模块划分图: (1)界面显示: Main() Taskstart() Taskstartdispinit() 在TaskStartDispInit()函数中,使用PC_DispStr()函数画出界面。

(2)按键查询与响应: Main() Taskstart() 在TaskStart()函数中,用if (PC_GetKey(&key) == TRUE)判断是否有按键输入。然后根据key 的值,判断输入的按键是哪一个;在响应中用switch语句来执行对应按键的响应。 (3)切换功能: l计数“C”按 键的次数 M=l%3 Switch(m) M=0,1,2对应于煮饭,煮粥,煮面,然后使用PC_DispStr()函数在选择的选项前画上“@”指示,同时,在其余两项钱画上“”以“擦出”之前画下的“@”,注意l自增。 四.主要代码: #include "stdio.h" #include "includes.h" #include "time.h" #include "dos.h" #include "sys/types.h" #include "stdlib.h" #define TASK_STK_SIZE 512 #define N_TASKS 2 OS_STK TaskStk[N_TASKS][TASK_STK_SIZE]; OS_STK TaskStartStk[TASK_STK_SIZE]; INT8U TaskData[N_TASKS];

操作系统实验报告

操作系统教程 实 验 指 导 书 姓名: 学号: 班级:软124班 指导老师:郭玉华 2014年12月10日

实验一WINDOWS进程初识 1、实验目的 (1)学会使用VC编写基本的Win32 Consol Application(控制台应用程序)。 (2)掌握WINDOWS API的使用方法。 (3)编写测试程序,理解用户态运行和核心态运行。 2、实验内容和步骤 (1)编写基本的Win32 Consol Application 步骤1:登录进入Windows,启动VC++ 6.0。 步骤2:在“FILE”菜单中单击“NEW”子菜单,在“projects”选项卡中选择“Win32 Consol Application”,然后在“Project name”处输入工程名,在“Location”处输入工程目录。创建一个新的控制台应用程序工程。 步骤3:在“FILE”菜单中单击“NEW”子菜单,在“Files”选项卡中选择“C++ Source File”, 然后在“File”处输入C/C++源程序的文件名。 步骤4:将清单1-1所示的程序清单复制到新创建的C/C++源程序中。编译成可执行文件。 步骤5:在“开始”菜单中单击“程序”-“附件”-“命令提示符”命令,进入Windows“命令提示符”窗口,然后进入工程目录中的debug子目录,执行编译好的可执行程序: E:\课程\os课\os实验\程序\os11\debug>hello.exe 运行结果 (如果运行不成功,则可能的原因是什么?) : 有可能是因为DOS下路径的问题 (2)计算进程在核心态运行和用户态运行的时间 步骤1:按照(1)中的步骤创建一个新的“Win32 Consol Application”工程,然后将清单1-2中的程序拷贝过来,编译成可执行文件。 步骤2:在创建一个新的“Win32 Consol Application”工程,程序的参考程序如清单1-3所示,编译成可执行文件并执行。 步骤3:在“命令提示符”窗口中运行步骤1中生成的可执行文件,测试步骤2中可执行文件在核心态运行和用户态运行的时间。 E:\课程\os课\os实验\程序\os12\debug>time TEST.exe 步骤4:运行结果 (如果运行不成功,则可能的原因是什么?) : 因为程序是个死循环程序 步骤5:分别屏蔽While循环中的两个for循环,或调整两个for循环的次数,写出运行结果。 屏蔽i循环: 屏蔽j循环: _______________________________________________________________________________调整循环变量i的循环次数:

实验二 读者写者问题实验报告..

实验二读者写者问题实验报告 一、实验目的 Windows2000/XP提供了互斥量(mutex)、信号量(semapore)、事件(event)等三种同步对象和相应的系统调用,用于线程的互斥与同步。通过对读者写者问题的调试,了解Windows2000/XP中的同步机制。 二、实验内容及实验步骤 利用Windows2000/XP信号量机制,实现读者写者问题。 在Windows 2000环境下,创建一个控制台进程,此进程包含n个线程。用这n个线程来表示n个读者或写者。每个线程按相应测试数据文件(后面有介绍)的要求进行读写操作。用信号量机制分别实现读者优先和写者优先的读者-写者问题。 读者-写者问题的读写操作限制(包括读者优先和写者优先): 写-写互斥,即不能有两个写者同时进行写操作。 读-写互斥,即不能同时有一个线程在读,而另一个线程在写。 读-读允许,即可以有一个或多个读者在读。 读者优先的附加限制:如果一个读者申请进行读操作时已有另一个读者正在进行读操作,则该读者可直接开始读操作。 写者优先的附加限制:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态才能开始读操作。 运行结果显示要求:要求在每个线程创建、发出读写操作申请、开始读写操作和结果读写操作时分别显示一行提示信息,以确定所有处理都遵守相应的读写操作限制。 三、实验结果及分析 图2.1 选择界面 第一字段为一个正整数,表示线程序号。第二字段表示相应线程角色,R 表示读者是,W 表示写者。第三字段为一个正数,表示读写操作的开始时间。线程创建

后,延时相应时间(单位为秒)后发出对共享资源的读写申请。第四字段为一个正数,表示读写操作的持续时间。当线程读写申请成功后,开始对共享资源的读写操作,该操作持续相应时间后结束,并释放共享资源。下面是一个测试数据文件的例子: 1 R 3 5 2 W 4 5 3 R 5 2 4 R 6 5 5 W 5.1 3 测试结果如下: 图2.2 读者优先运行结果

操作系统OS报告读者与写者问题(进程同步问题)

目录 一、课程设计目的及要求 (1) 二、相关知识 (1) 三、题目分析 (2) 四、概要设计 (4) 五、代码及流程 (5) 六、运行结果 (11) 七、设计心得 (12) 八、参考文献 (12)

一、课程设计目的及要求 读者与写者问题(进程同步问题) 用n 个线程来表示n个读者或写者。每个线程按相应测试数据文件的要求,进行读写操作。请用信号量机制分别实现读者优先和写者优先的读者-写者问题。 读者-写者问题的读写操作限制: 1)写-写互斥; 2)读-写互斥; 3)读-读允许; 写者优先的附加限制:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。 二、相关知识 Windows API: 在本实验中涉及的API 有: 1线程控制: CreateThread 完成线程创建,在调用进程的地址空间上创建一个线程,以执行指定的函数;它的返回值为所创建线程的句柄。 HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD DWORD dwStackSize, // initial stack size LPTHREAD_START_ROUTINE lpStartAddress, // thread function LPVOID lpParameter, // thread argument DWORD dwCreationFlags, // creation option LPDWORD lpThreadId // thread identifier ); 2 ExitThread 用于结束当前线程。 VOID ExitThread( DWORD dwExitCode // exit code for this thread ); 3Sleep 可在指定的时间内挂起当前线程。 VOID Sleep( DWORD dwMilliseconds // sleep time ); 4信号量控制: WaitForSingleObject可在指定的时间内等待指定对象为可用状态; DWORD WaitForSingleObject( HANDLE hHandle, // handle to object DWORD dwMilliseconds // time-out interval );

操作系统读者写者实验报告

《操作系统》上机实验报告 实验项目读者写者 学院(部)信息学院 专业计算机科学与技术班级 学生姓名 学号

读者写者问题 一.实验目的: 1.熟悉读者优先和写者优先的过程。 2.更好地理解进程同步的概念及其实现方法。 二.实验要求: 分别实现读者优先和写者优先。 “读-写”互斥,即不能同时有一个读者在读,同时去有一个写者在写; “写-写”互斥,即不能有两个写者同时进行写操作; “读-读”允许,即可以有两个以上的读者同时进行读操作。 三.实验内容: 读者优先: 如果没有写者正在操作,则读者不需要等待,用一个整型变量readcount 记录当前的读者数目,用于确定是否释放写者线程,(当readcout=0 时,说明所有的读者都已经读完,释放一个写者线程),每个读者开始读之前都要修改readcount,为了互斥的实现对readcount 的修改,需要一个互斥对象Mutex来实现互斥。 另外,为了实现写-写互斥,需要一个临界区对象write,当写者发出写的请求时,必须先得到临界区对象的所有权。通过这种方法,可以实现读写互斥,当readcount=1 时,(即第一个读者的到来时,),读者线程也必须申请临界区对象的所有权. 当读者拥有临界区的所有权,写者都阻塞在临界区对象write上。当写者拥有临界区对象所有权时,第一个判断完readcount==1 后,其余的读者由于等待对readcount的判断,阻塞在Mutex上! 写者优先: 写者优先和读者优先有相同之处,不同的地方在:一旦有一个写者到来时,应该尽快让写者进行写,如果有一个写者在等待,则新到的读者操作不能读操作,为此添加一个整型变量writecount,记录写者的数目,当writecount=0时才可以释放读者进行读操作!为了实现对全局变量writecount的互斥访问,设置了一个互斥对象Mutex3。 为了实现写者优先,设置一个临界区对象read,当有写者在写或等待时,读者必须阻塞在临界区对象read上。 读者除了要一个全局变量readcount实现操作上的互斥外,还需要一个互斥对象对阻塞在read这一个过程实现互斥,这两个互斥对象分别为mutex1和mutex2。

操作系统课程设计--读者-写者问题

操作系统课程设计报告 一、操作系统课程设计任务书 读者- 写者问题实现 1设计目的通过实现经典的读者写者问题,巩固对线程及其同步机制的学习效果,加深对相关基本概念的理解,并学习如何将基本原理和实际设计有机的结合。 2设计要求 在Windows 2000/XP 环境下,使用多线程和信号量机制实现经典的读者写者问题,每个线程代表一个读者或一个写者。每个线程按相应测试数据文件的要求,进行读写操作。请用信号量机制分别实现读者优先和写者优先的读者- 写者问题。 读者-写者问题的读写操作限制: (1)写-写互斥,即不能有两个写者同时进行写操作 (2)读-写互斥,即不能同时有一个读者在读,同时却有一个写者在写 (3)读-读允许,即可以有二个以上的读者同时读读者优先的附加限制:如果一个读者申请进行读操作时已有另一读者正在进行读操作,则该读者可直接开始读操作。 写者优先的附加限制:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。 运行结果显示要求:要求在每个线程创建、发出读写操作申请、开始读写操作和结束读写操作时分别显示一行提示信息,以确信所有处理都遵守相应的读写操作限制。 3测试数据文件格式 测试数据文件包括n 行测试数据,分别描述创建的n 个线程是读者还是写者,以及读写操作的开始时间和持续时间。每行测试数据包括四个字段,各字段间用空格分隔。第一字段为一个正整数,表示线程序号。第二字段表示相应线程角色,R 表示读者是,W 表示写者。第三字段为一个正数,表示读写操作的开始时间。线程创建后,延时相应时间(单位为秒)后发出对共享资源的读写申请。第四字段为一个正数,表示读写操作的持续时

嵌入式实时操作系统实验报告

嵌入式实时操作系统实验报告 任务间通信机制的建立 系别计算机与电子系 专业班级***** 学生姓名****** 指导教师 ****** 提交日期 2012 年 4 月 1 日

一、实验目的 掌握在基于嵌入式实时操作系统μC/OS-II的应用中,任务使用信号量的一般原理。掌握在基于优先级的可抢占嵌入式实时操作系统的应用中,出现优先级反转现象的原理及解决优先级反转的策略——优先级继承的原理。 二、实验内容 1.建立并熟悉Borland C 编译及调试环境。 2.使用课本配套光盘中第五章的例程运行(例5-4,例5-5,例5-6),观察运行结果,掌握信号量的基本原理及使用方法,理解出现优先级反转现象的根本原因并提出解决方案。 3.试编写一个应用程序,采用计数器型信号量(初值为2),有3个用户任务需要此信号量,它们轮流使用此信号量,在同一时刻只有两个任务能使用信号量,当其中一个任务获得信号量时向屏幕打印“TASK N get the signal”。观察程序运行结果并记录。 4. 试编写一个应用程序实现例5-7的内容,即用优先级继承的方法解决优先级反转的问题,观察程序运行结果并记录。 5.在例5-8基础上修改程序增加一个任务HerTask,它和YouTask一样从邮箱Str_Box里取消息并打印出来,打印信息中增加任务标识,即由哪个任务打印的;MyTask发送消息改为当Times为5的倍数时才发送,HerTask接收消息采用无等待方式,如果邮箱为空,则输出“The mailbox is empty”, 观察程序运行结果并记录。 三、实验原理 1. 信号量 μC/OS-II中的信号量由两部分组成:一个是信号量的计数值,它是一个16位的无符号整数(0 到65,535之间);另一个是由等待该信号量的任务组成的等待任务表。用户要在OS_CFG.H中将OS_SEM_EN开关量常数置成1,这样μC/OS-II 才能支持信号量。

操作系统实验报告

操作系统教程实验报告 专业班级 学号 姓名 指导教师

实验一WINDOWS进程初识 1、实验目的 (1)学会使用VC编写基本的Win32 Consol Application(控制台应用程序)。 (2)掌握WINDOWS API的使用方法。 (3)编写测试程序,理解用户态运行和核心态运行。 2、实验内容和步骤 (1)编写基本的Win32 Consol Application 步骤1:登录进入Windows,启动VC++ 6.0。 步骤2:在“FILE”菜单中单击“NEW”子菜单,在“projects”选项卡中选择“Win32 Consol Application”,然后在“Project name”处输入工程名,在“Location”处输入工程目录。创建一个新的控制台应用程序工程。 步骤3:在“FILE”菜单中单击“NEW”子菜单,在“Files”选项卡中选择“C++ Source File”, 然后在“File”处输入C/C++源程序的文件名。 步骤4:将清单1-1所示的程序清单复制到新创建的C/C++源程序中。编译成可执行文件。 步骤5:在“开始”菜单中单击“程序”-“附件”-“命令提示符”命令,进入Windows “命令提示符”窗口,然后进入工程目录中的debug子目录,执行编译好的可执行程序:E:\课程\os课\os实验\程序\os11\debug>hello.exe 运行结果 (如果运行不成功,则可能的原因是什么?) : (2)计算进程在核心态运行和用户态运行的时间 步骤1:按照(1)中的步骤创建一个新的“Win32 Consol Application”工程,然后将清单1-2中的程序拷贝过来,编译成可执行文件。 步骤2:在创建一个新的“Win32 Consol Application”工程,程序的参考程序如清单1-3所示,编译成可执行文件并执行。 步骤3:在“命令提示符”窗口中运行步骤1中生成的可执行文件,测试步骤2中可执行文件在核心态运行和用户态运行的时间。 E:\课程\os课\os实验\程序\os12\debug>time TEST.exe 步骤4:运行结果 (如果运行不成功,则可能的原因是什么?) : 步骤5:分别屏蔽While循环中的两个for循环,或调整两个for循环的次数,写出运行结果。 屏蔽i循环:

操作系统课程设计-读者写者问题

操作系统课程设计报告

一、开题报告 (一)该项课程设计的意义; 1.更加深入的了解读者写者问题的算法; 2.加深对线程,进程的理解; 3.加深对“线程同步”概念的理解,理解并应用“信号量机制”; 4.熟悉计算机对处理机的管理,了解临界资源的访问方式; 5.了解C++中线程的实现方式,研读API。 (二)课程设计的任务 多进程/线程编程:读者-写者问题。 ●设置两类进程/线程,一类为读者,一类为写者; ●随机启动读者或写者; ●显示读者或写者执行状态; ●随着进程/线程的执行,更新显示; (三)相关原理及算法描述; 整体概况: 该程序从大体上来分只有两个模块,即“读者优先”和“写者优先”模块. 读者优先: 如果没有写者正在操作,则读者不需要等待,用一个整型变量readcount记录读者数目,用于确定是否释放读者线程,readcount的初值为0.当线程开始调入时. 每个读者准备读. 等待互斥信号,保证对readcount 的访问,修改互斥.即readcount++. 而当读者线程进行读操作时,则读者数目减少(readcount--).当readcout=0 时,说明所 有的读者都已经读完,离开临界区唤醒写者(LeaveCriticalSection(&RP_Write);), 释 放互斥信号(ReleaseMutex(h_Mutex)). 还需要一个互斥对象mutex来实现对全局变量Read_count修改时的互斥. 另外,为了实现写-写互斥,需要增加一个临界区对象Write。当写者发出写请求时, 必须申请临界区对象的所有权。通过这种方法,可以实现读-写互斥,当 Read_count=1时(即第一个读者到来时),读者线程也必须申请临界区对象的所有 权 写者优先: 写者优先与读者不同之处在于一旦一个写者到来,它应该尽快对文件进行写操作,如果有一个写者在等待,则新到来的读者不允许进行读操作。为此应当填加 一个整形变量write_count,用于记录正在等待的写者的数目,write_count的初值 为0.当线程开始调入时.只允许一个写者准备读. 等待互斥信号,保证对write_count 的访问,修改互斥.即write_count++.而当写者线程进行读操作时,则相应写者数目减 少(write_count--).当write_count=0 时,说明所有的读者都已经读完,离开临界区唤 醒读者,释放互斥信号. 为了实现写者优先,应当填加一个临界区对象read,当有写者在写文件或等待时,读者必须阻塞在read上。

读者写者问题写者优先代码

读者写者问题-写者优先代码 #include<stdio.h> #include<stdlib.h> int rcount=0;//正在读的读者数量 int wcount=0;//写者队列中等待写操作的写者数量 int rid=0;//读进程号 int wid=0;//写进程号 int w=1;//读写互斥信号量 char temp[300] = {'\0'}; int sign; //标识temp空的信号量0表示temp空 void WFwakeup(); void RFwakeup(); struct rqueue{//读者等待队列 int readers[200]; int index; }rq; struct wqueue{//写者等待队列 int writers[200]; int index; }wq; void read(){ int i = 0; rid++; if(rcount == 0){//当前没有读进程在读可能有写进程在写可能CPU空闲if(w==1) {//如果CPU空闲,读者拿到CPU w--;// 相当于一个P操作 rcount++; if(temp[0] == '\0'){ sign = 0; rq.readers[rq.index++]=rid;//将读者进程加入等待队列 WFwakeup(); return; }//if printf("读者%d正在读\n",rid);

for(i = 0;i < 300;i++){//读取temp内容即写者写的内容 if(temp[i] == '\0'){ printf("\n"); return; }//if printf("%c",temp[i]); }//for }//if else{//写者线程正在执行 printf("有写者在写不能读!\n"); rq.readers[rq.index++]=rid;//将读者进程加入等待队列 }//else }//if else{//rcount !=1 则知道当前已经有读者在读,读读不互斥,则这个读者可以直接进来了读 printf("读者%d正在读\n",rid); for(i = 0;i < 300;i++){ if(temp[i] == '\0'){ printf("\n"); return; } printf("%c",temp[i]); }//for }//else } //***************************写进程写操作 void write(){ wid++; if(w == 0){ if(rcount != 0 ){//有读者进程在执行 printf("有读者在读不能写!\n"); wq.writers[wq.index++]=wid;//将写者进程加入等待队列 wcount++; return; } if(rcount == 0 ){//rcount == 0则当前无读者,但w = 0,所以有写者在写 printf("有写者在写不能写!\n"); wq.writers[wq.index++]=wid;//将写者进程加入等待队列 wcount++; return; } }

操作系统实验报告

实验报告 实验课程名称:操作系统 实验地点:南主楼七楼机房 2018—2019学年(一)学期 2018年 9月至 2019 年 1 月 专业: 班级: 学号: 姓名: 指导老师:刘一男

实验一 实验项目:分时系统模拟 实验学时:2实验日期: 2018-10-25 成绩: 实验目的利用程序设计语言模拟分时系统中多个进程按时间片轮转调度算法进行进程调度的过程; 假设有五个进程A,B,C,D,E,它们的到达时间及要求服务的时间分别为:进程名 A B C D E 到达时间0 1 2 3 4 服务时间 4 3 4 2 4 时间片大小为1,利用程序模拟A,B,C,D,E五个进程按时间片轮转的调度及执行过程并计算各进程的周转时间及带权周转时间。 执行过程并计算各进程的周转时间及带权周转时间。 轮转调度:BDACE

(1)修改时间片大小为2,利用程序模拟A,B,C,D,E五个进程按时间片轮转的调度及执行过程并计算各进程的周转时间及带权周转时间。 轮转调度:ADBCE (2)修改时间片大小为4,利用程序模拟A,B,C,D,E五个进程按时间片轮转的调度及执行过程并计算各进程的周转时间及带权周转时间.

顺序:ABCDE 1、思考 时间片的大小对调度算法产生什么影响?对计算机的性能产生什么影响?答:通过对时间片轮转调度算法中进程最后一次执行时间片分配的优化,提出了一种改进的时间片轮转调度算法,该算法具有更好的实时性,同时减少了任务调度次数和进程切换次数,降低了系统开销,提升了CPU的运行效率,使操作系统的性能得到了一定的提高。 A B C D E 时间片为1 周转时间12 9 14 8 13 3 3 3.5 4 3.25 带权周转 时间 时间片为2 周转时间8 12 13 7 13 2 4 3.25 3.5 3.25 带权周转 时间 时间片为4 周转时间 4 6 9 10 13 1 2 2.25 5 3.25 带权周转 时间

操作系统实验一实验报告

操作系统实验一实验报告 基本信息 1.1 实验题目 进程控制实验 1.2完成人 王召德 1.3报告日期 2015-4-8 实验内容简要描述 2.1实验目标 加深对于进程并发执行概念的理解。实践并发进程的创建和控制方法。观察和 体验进程的动态特性。进一步理解进程生命期期间创建、变换、撤销状态变换的过 程。掌握进程控制的方法,了解父子进程间的控制和协作关系。练习Linux 系统中 进程创建与控制有关的系统调用的编程和调试技术。 2.2实验要求 参考以上示例程序中建立并发进程的方法,编写一个多进程并发执行程序。父进程首先创建一个执行ls命令的子进程然后再创建一个执行ps命令的子进程,并控制ps 命令总在ls 命令之前执行。 2.3实验的软硬件环境

Ubuntu14.04 intelPC 报告的主要内容 3.1实验的思路 按照上面的实例,先生成一个子进程让其等待,然后生成第二个子进程,父进程等待其执行ps命令后唤醒第一个子进程执行ls即可。 3.2实验模型的描述 无 3.3主要数据结构的分析说明 无 3.4主要算法代码的分析说明 无 3.5项目管理文件的说明 无 实验过程和结果 4.1实验投入的实际学时数 1学时 4.2调试排错过程的记录 曾尝试让第二个子进程激活第一个子进程,结果发现当运行ps后,后面的代码将不再执行,所以不可行。 4.3多种方式测试结果的记录

实验结果: 父进程启动 (12239) ls子进程启动 (12240) ps子进程启动 (12241) PID TTY TIME CMD 12239 pts/27 00:00:00 born 12240 pts/27 00:00:00 born 12241 pts/27 00:00:00 ps ps子进程结束 (12241) 唤醒ls子进程 (12240) 键盘中断信号产生... ls子进程被唤醒 (12240) . born born.c~ hello.c pctl pctl.c~ pctl.o .. born.c helelo.h~ hello.c~ pctl.c pctl.h ls子进程结束 (12240) 父进程结束 (12239) 4.4实验结果的分析综合 无 实验的总结 父进程可以通过fork()函数生成子进程,子进程会从fork()函数开始执行原来的代码,当

相关文档
最新文档