若对你有帮助,记得点赞、关注我哦!

4个题目:进程创建及创建过程分析、进程族亲关系分析、进程间软中断通信、进程间管道通信(欢迎评论/私信)

笔者用的是“ProcessOn免费在线作图网站”作的图。

报告格式要求:正文{中文:宋体、五号、单倍距;英文:Times New Roman、11号、单倍距}

一级标题{宋体、小三号、加粗}    二级标题{四号}    三级标题{小四}不允许有四级标题

图命名{在图下方居中、宋体、五号、仅允许出现2级图名eg.3-1<空格>名称}    图中文字{宋体、小五}

表命名{在表上方居中、......}     表中文字{......}

页眉{学号<空格>姓名、宋体、小四、居中}     页脚{目录页码用罗马数字、正文页码用阿拉伯数字}

注*参考文献格式要求、缩进要求

题目1  进程创建及创建过程分析  参看书P163~166

1.1设计目的

灵活运用fork系统调用创建进程,深入分析进程创建过程及fork系统调用返回值的含义,透彻分析父子进程代码共享、执行流程及数据集合的变化轨迹。

1.2设计要求

设计的程序能体现出父子进程执行轨迹的差别,也能体现出父子进程数据集合的差别。

1.3程序源代码

#include<stdio.h>
#include<unistd.h>
pid_t fork(void);
int main()
{printf("parent pid=%d\n",getpid());pid_t pid=fork();int x=0;if(pid==0){x=x+1;printf("child pid=%d,x=%d,&x=%p\n",getpid(),x,&x);}else{x=x-1;printf("parent pid=%d,x=%d,&x=%p\n",getpid(),x,&x);}sleep(10);
}

1.4运行结果

图1-1 父子进程创建的运行结果

1.5相关图表

图1-2 与进程对应的PCB和数据集示意图

图1-3 fork系统调用如何创建进程

图1-4 fork系统调用返回后父子进程的执行路径

执行步骤:

(1)程序启动时,系统加载程序,为变量分配内存,为父进程创建进程控制块PCB,并在其中填写分配给该进程的PID(此处为3416)、代码地址、数据集地址和其他属性,在进程数据集中x和PID的内容不定。

(2)父进程执行赋值语句“x=0”:程序将整数0写入变量x所在的存储单元。

(3)父进程执行fork系统调用:

①系统首先创建子进程PCB,内容从父进程PCB复制而来,但pid是新分配的唯一整数(此处为3417);

②创建父进程数据集的一个副本,保存于新分配的存储器中,作为子进程数据集,其中变量x的值也是0,以后子进程仅对属于自己的数据集进行操作;

③子进程PCB中的数据集地址指向子进程自己的数据集,有了程序代码、数据集和PCB,一个完整的子进程就创建出来了。这样子进程除pid与父进程不同外,程序代码和数据集都与父进程一样,fork函数完成了对父进程的复制工作;

④由于子进程从父进程复制而来,程序计数器PC中具有相同的地址。当获得CPU后,下一条指令或语句也与父进程一致,父进程接下来从fork系统调用返回,子进程也一样。在父子进程的数据集中都有一个“fork函数返回值”项,父进程fork系统调用的返回值为子进程的pid(此处为3417),子进程的fork返回值为0,并由系统填入父子进程的数据集中。

(4)fork系统调用返回后父子进程的执行路径:

①fork系统调用完成子进程的创建后,父子进程都有相同的程序代码,从函数调用返回开始往下执行,从数据集中读取fork返回值,赋值给pid变量,因此父进程的pid变量被写入3417,子进程的pid变量被写入0;

②接下来父子进程都往下执行,判断if条件,决定是否执行if分支。由于父进程pid>0,子进程pid==0,因此父进程将进入if(pid>0)分支,子进程将进入if(pid==0)分支;

③父进程执行if(pid>0)分支时,遇到x=x-1语句,将x(初值为0)减1后写回变成-1,并输出“父进程的PID、x的值和x的地址”;子进程执行if(pid==0)时,遇到x=x+1语句,将x(初值为0)加1后变成1,并输出“子进程的PID、x的值和x的地址”;

④完成if语句块后,两进程都要执行最后的“sleep(10);”语句,睡眠10秒,让用户有时间查看进程信息。

1.6参考文献

[1]徐钦桂,徐治根,黄培灿,谢伟鹏. Linux编程[M]. 北京:清华大学出版社,2019:163-166.

1.7心得

通过本次课程设计我学会灵活运用fork系统调用创建进程,深入分析进程创建过程及fork系统调用返回值的含义,透彻分析父子进程代码共享、执行流程及数据集合的变化轨迹。

fork函数时调用一次,返回两次。在父进程和子进程中各调用一次。子进程中返回值为0,父进程中返回值为子进程的PID。可以根据返回值的不同让父进程和子进程执行不同的代码。子进程是父进程的副本,获得了父进程数据空间、堆和栈的副本;父子进程并不共享这些存储空间,即代码段;因此子进程对变量的所做的改变并不会影响父进程。一般来说,fork之后父、子进程执行顺序是不确定的,这取决于内核调度算法。进程之间实现同步需要进行进程通信。

题目2  进程族亲关系分析  参看书P166~169

2.1设计目的

通过画进程族亲关系图来帮助理解多进程应用程序,从而获得编写多进程并发程序的能力。

2.2设计要求

仿照教材图5-16分析进程族亲关系。针对教材习题5.10进行调试、运行、分析,并对程序做适当修改后再分析输出结果。

2.3程序源代码

#include<unistd.h>
int flag=1;
int main(){pid_t pid;pid=fork();if(pid>0)flag=flag+1;if(pid==0)flag=flag+2;pid=fork();if(pid>0)flag=flag+10;if(pid==0)flag=flag+20;pid=fork();if(pid>0)flag=flag+100;if(pid==0)flag=flag+200;pid=fork();if(pid>0)flag=flag+1000;if(pid==0)flag=flag+2000;printf("flag=%d,pid=%d\n",flag,getpid());
}

2.4运行结果

图2-1 进程族亲关系的运行结果

2.5相关图表

图2-2 进程族亲关系分析和进程图画法

程序执行和进程产生过程:

(1)程序启动时,系统创建进程p1(flag=1);p1执行程序中的第一个fork函数调用,创建子进程p11(flag=1),两个进程的pid变量值分别为p11的PID和0,即p1.pid=PID(p11),p11.pid=0。

(2)条件pid>0为真的进程p1将flag加1变成2;条件pid==0为真的进程p11将flag加2变成3。

(3)接着p1、p11都执行程序中的第二个fork函数调用,分别创建进程p12(flag=2)和p111(flag=3),四个进程的pid变量值分别为p1.pid=PID(p12)、p11.pid=PID(p111)、p12.pid=0、p111.pid=0。

(4)条件pid>0为真的进程p1和p11将flag加10变成12和13;条件pid==0为真的进程p12和p111将flag加20变成22和23。

(5)第三个fork函数调用和其后的两个if语句,执行步骤同第(3)和(4)步,简写成:

p1:flag=12+100=112   p11:flag=13+100=113   p111:flag=23+100=123

p12:flag=22+100=122

新的子进程p13:flag=12+200=212   p112:flag=13+200=213   p121:flag=22+200=222   p1111:flag=23+200=223

(6)第四个fork函数调用和其后的两个if语句,执行步骤同第(3)和(4)步,简写成:

p1:flag=112+1000=1112   p11:flag=113+1000=1113   p111:flag=123+1000=1123

p12:flag=122+1000=1122   p13:flag=212+1000=1212   p112:flag=213+1000=1213

p121:flag=222+1000=1222   p1111:flag=223+1000=1223

新的子进程p14:flag=112+2000=2112   p131:flag=212+2000=2212

p122:flag=122+2000=2122   p1211:flag=222+2000=2222

p113:flag=113+2000=2113   p1121:flag=213+2000=2213

p1112:flag=123+2000=2123   p11111:flag=223+2000=2223

(7)最后,16个进程均往下执行printf,产生16行输出,并分别执行sleep(10)语句睡眠10秒而终止。

2.6参考文献

[1]徐钦桂,徐治根,黄培灿,谢伟鹏. Linux编程[M]. 北京:清华大学出版社,2019:166-169.

2.7心得

在本次课程设计中,我学会了通过画进程族亲关系图来帮助理解多进程应用程序,从而获得编写多进程并发程序的能力。

进程族亲关系图让我清楚地明白了进程间错综复杂的父子关系,以及fork系统调用后又是如何“繁衍后代”的。赋予代代子孙们的变量flag同它们固有的PID一样不会互相重复,这种方式能更加唯一标识一个进程。

题目3  进程间软中断通信  参看书P186~193

3.1设计目的

理解进程间软中断通信机制。

3.2设计要求

使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上发出的中断信号(即按Ctrl+C键),当父进程接收到这两个软中断的其中一个后,父进程用系统调用kill()向两个子进程分别发送整数值为16和17软中断信号,子进程获得对应软中断信号,然后分别输出下列信息后终止:

Child process 1 is killed by parent!!

Child process 2 is killed by parent!!

父进程调用wait()函数等待两个子进程终止后,输出以下信息,结束进程执行:

Parent process is killed!!

多运行几次编写的程序,简略分析出现不同结果的原因。

3.3程序源代码

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int flag_wait = 1;
void stop2()
{flag_wait = 0;printf("Child interruption\n");
}
void stop1()
{printf("Parent interruption\n");
}
int main()
{pid_t pid1, pid2;//当接受到按下Ctrl+C时产生的SIGINT信号时,调用stop1()signal(SIGINT, stop1);//创建子进程1do{pid1 = fork();} while (pid1 < 0);if (pid1 > 0){//创建子进程2do{pid2 = fork();} while (pid2 < 0);if (pid2 > 0){sleep(5);//向子进程1发送中断信号16kill(pid1, 16);wait(0);//向子进程2发送中断信号17kill(pid2, 17);wait(0);printf("Parent process is killed!!\n");exit(0);}else{//当接受到信号17时,调用stop2()signal(17, stop2);//死循环直到接收到中断信号while (flag_wait);printf("Child process 2 is killed by parent!!\n");exit(0);}}else{//当接受到信号16时,调用stop2()signal(16, stop2);//死循环直到接收到中断信号while (flag_wait);printf("Child process 1 is killed by parent!!\n");exit(0);}return 0;
}

3.4运行结果

图3-1 执行5秒后自动运行结果

图3-2 执行时按下Ctrl+C键后的运行结果

程序执行步骤:

(1)创建两个pid_t类型的变量pid1和pid2;

(2)再用系统调用signal()让父进程捕捉键盘上发出的中断信号(即按Ctrl+C键)

①当父进程接收到这个软中断(Ctrl+C)后,输出“Parent interruption”;

②当父进程未收到软中断(Ctrl+C),则继续往下执行;

(3)fork系统调用创建子进程pid1和pid2;

(4)如果当前运行的是子进程pid1和pid2,则在它们得到软中断信号后终止,并输出“Child process 1 is killed by parent!!”、“Child process 2 is killed by parent!!”;

(5)如果当前运行的是父进程,则一起随眠5秒,再分别向子进程1和2发送中断信号16和17,父进程调用wait()函数等待两个子进程终止后,输出“Parent process is killed!!”,结束进程执行。

3.5相关图表

图3-3 进程间软中断通信的流程图

3.6参考文献

[1]徐钦桂,徐治根,黄培灿,谢伟鹏. Linux编程[M]. 北京:清华大学出版社,2019:186-193.

3.7心得

通过本次课程设计我理解了进程间软中断通信机制。软中断信号(signal)是一种简单且最基本的进程通信机制,它最大的特点是提供了一种简单的处理异步事件的方法。例如,常见的用户从键盘键入组合键Ctrl+C来中断一个程序的运行,或者在两个进程之间通过某个信号来通知发生了异步事件,或者向系统或进程报告突发的硬件故障,如非法指令、运算溢出等。更重要的是,用户进程还可以向自己发送信号以中断进程的执行,并自动转入指定的软中断处理函数去执行用户自行安排的处理内容,处理完毕后再返回用户进程继续执行,从而为应用程序提供了由用户自行处理随机事件的通信机制。

软中断信号实现 (signal implementation) 是操作系统用来通知进程有事情发生的一种机制。由于这种信号总是在进程处于运行状态时才会去响应,故称之为软中断信号。软中断信号的使用者是操作系统和源程序,操作系统事先将系统的中可以使用的软件中断信号进行集中编码并定义相应含义后,提交用户使用。用户可以通过相应的软件中断序号或软中断名称来使用软中断,二者在使用上是等效的。用户只能在操作系统提供的软件中断序号范围内使用软件中断信号,不能自己创建新的软件中断信号。如果用户的应用程序之间有信号需要发送,则可以使用操作系统预留给用户使用的用户信号 SIGUSR1 或用户信号 SIGUSR2。

题目4  进程间的管道通信  参看书P278~281

4.1设计目的

理解进程间管道通信机制。

4.2设计要求

使用系统调用pipe()建立一条管道线,两个子进程分别向管道各写一句话:

Child process1 is sending a message!

Child process2 is sending a message!

而父进程则从管道中读出来自两个子进程的信息,显示在屏幕上。

要求:父进程先接受子进程P1发来的消息,然后再接受子进程P2发来的消息。

4.3程序源代码

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<signal.h>
#include<sys/wait.h>
int main()
{pid_t pid1,pid2;  //定义两个进程变量int fd[2];char OutPipe[100],InPipe[100];  //定义两个字符数组pipe(fd);  //创建管道while((pid1=fork())==-1);  //如果进程1创建不成功,则空循环if(pid1==0)  //如果子进程1创建成功,pid1为进程号{lockf(fd[1],1,0);  //锁定管道sprintf(OutPipe,"Child process 1 is sending message!\n");  //给OutPipe赋值write(fd[1],OutPipe,50);      //向管道写入数据sleep(1);  //等待读进程读出数据lockf(fd[1],0,0);  //解除管道的锁定exit(0);  //结束进程1}else{while((pid2=fork())==-1);  //若进程2创建不成功,则空循环if(pid2==0){lockf(fd[1],1,0);sprintf(OutPipe,"Child process 2 is sending message!\n");write(fd[1],OutPipe,50);         sleep(1);lockf(fd[1],0,0);exit(0);}else{wait(0);  //等待子进程1结束read(fd[0],InPipe,50);  //从管道中读出数据printf("read:%s\n",InPipe);  //显示读出的数据wait(0);  //等待子进程2结束read(fd[0],InPipe,50);printf("read:%s\n",InPipe);  //父进程结束exit(0);}}return 0;
}

4.4运行结果

图4-1 进程间管道通信的运行结果

4.5相关图表

图4-2 进程间管道通信流程图

4.6参考文献

[1]徐钦桂,徐治根,黄培灿,谢伟鹏. Linux编程[M]. 北京:清华大学出版社,2019:278-281.

4.7心得

通过本次课程设计我理解了进程间软管道通信机制。

pipe管道,又称pipe文件,它用于连接一个读进程和一个写进程,以实现它们之间的信息共享。向管道(共享文件)提供输入的发送进程(即写进程),以字符流形式将大量的数据送入管道;而接受管道输出的接收进程(即读进程),可以从管道中接收(读)数据。

为了协调双方的通信,管道机制必须提供以下三方面的协调能力:

(1)互斥:当一个进程正在对pipe执行读/写操作时,其它(另一)进程必须等待,程序中使用lockf(fd[1],1,0)函数实现对管道的加锁操作,用lockf(fd[1],0,0)解除管道的锁定。

(2)同步:当写(输入)进程把一定数量(如4KB)的数据写入pipe后,便去睡眠等待,直到读(输出)进程取走数据后,再把它唤醒。当读进程试图从一空pipe中读取数据时,也应睡眠等待,直至写进程将数据写入管道后,才将之唤醒。

(3)确定对方是否存在:只有确定了写进程和读进程都存在的情况下,方能通过管道进行通信。

Linux课程设计报告【全集】相关推荐

  1. 嵌入式linux设计报告,嵌入式linux课程设计报告

    嵌入式linux课程设计报告 重庆科技学院 课程设计成果 院(系):_电气与信息工程学院_ 班 级: 计科普0802 学生姓名: 庄桐泉 学 号: 2008441067 设计地点(单位)___ _I3 ...

  2. 嵌入式linux设计报告,[嵌入式linux课程设计报告.doc

    [嵌入式linux课程设计报告 重庆科技学院 课程设计成果 院(系):_电气与信息工程学院_ 班 级: 计科普0802 学生姓名: 庄桐泉 学 号: 2008441067 设计地点(单位)___ _I ...

  3. 课程设计报告linux小游戏,嵌入式课程设计报告---贪吃蛇游戏.doc

    嵌入式课程设计报告---贪吃蛇游戏 嵌入式系统课程设计报告书 课题题目:贪吃蛇游戏 学 院:核自院 班 级:测控三班 学 号:9 姓 名: 马文铂 第一章 引言- 2 - 1.1关于题目- 2 - 1 ...

  4. linux课程设计题目主存空间的分配与回收,可变分区分配与回收,哈尔滨理工大学操作系统课程设计报告.doc-资源下载在线文库www.lddoc.cn...

    可变分区分配与回收,哈尔滨理工大学 操作系统课程设计报告.doc 哈 尔 滨 理 工 大 学 课 程 设 计 ( 操 作 系 统 ) 题 目 可变分区分配与回收 (首次适应算法) 班 级 计算机科学与 ...

  5. linux课程设计死锁避免,linux操作系统课程设计—车辆死锁.doc

    linux操作系统课程设计-车辆死锁.doc 键入文字"操作系统原理"课程设计BX090709吴沛儒操作系统原理课程设计报告姓名吴沛儒班级BX0907学号9指导老师胡静二〇一一年十 ...

  6. android应用课程设计报告,基于Android的多媒体播放器课程设计报告.doc

    基于Android的多媒体播放器课程设计报告.doc 基于Android的多媒体播放器课程设计报告2014-01-02 224652 转载标签 android多媒体播放器嵌入式课程设计报告it分类 我 ...

  7. 华科计算机课程设计,华中科大操作系统课程设计报告(附源码).doc

    华中科技大学计算机学院 操作系统课程设计报告 班级: 学号: 姓名:彭博 时间:2010年3月 设计内容一:熟悉和理解Linux编程环境 编写一个C程序,实现文件拷贝功能. 2)编写一个C程序,使用下 ...

  8. Java课程设计报告--绩效考核信息管理系统

     Java课程设计报告 题目      绩效考核信息管理系统    学生姓名         学    号                   院    系        年级专业计算机科学与技术 班 ...

  9. 网络协议分析与仿真课程设计报告:网络流量分析与协议模拟

    公众号:CS阿吉 网络协议分析与仿真课程设计报告  题  目:网络流量分析与协议模拟 专业名称:         网络工程 班    级: 学生姓名:           阿吉 学号(8位): 指导教 ...

  10. android媒体播放器设计报告,基于Android的多媒體播放器课程设计报告.doc

    基于Android的多媒體播放器课程设计报告 基于Android的多媒体播放器课程设计报告 (2014-01-02 22:46:52) HYPERLINK "javascript:;&quo ...

最新文章

  1. Linux内存手动释放方法
  2. 5.8 正则化和数据标准化
  3. linux下python脚本print中文显示不正确_在终端上运行python脚本,没有打印或显示-为什么?...
  4. Spark On MaxCompute如何访问Phonix数据
  5. Node.js 应用故障排查手册 —— 雪崩型内存泄漏问题
  6. 谷歌浏览器怎么重发请求_Googel 浏览器 模拟发送请求工具--Advanced REST Client
  7. 理论基础 —— 查找 —— 顺序查找
  8. 什么样的外链才是高质量的外链|网站优化
  9. python中文视频教程-鱼C零基础入门 Python中文视频教程
  10. 复化梯形公式求二重积分matlab源码
  11. 清华大学计算机专业在职博士吧,清华大学在职博士含金量高吗?
  12. 简单的c++对象模型
  13. iphone java模拟器_【Mac + Appium + Java1.8学习(三)】之IOS自动化环境安装配置以及简单测试用例编写(模拟器、真机)...
  14. Desktop no head
  15. 罗技无线网卡linux,Linux Kernel 5.2将改进对Logitech无线设备的支持
  16. error C2039: ‘tr1‘: is not a member of ‘std‘
  17. 毕业设计-基于SpringBoot幼儿园管理系统
  18. 基于python-opencv给图像添加水印
  19. 四十七、使用bootstrap中的选项卡制作产品特色页面
  20. Python读写文件(txt, csv等)小结

热门文章

  1. 2021年N1叉车司机最新解析及N1叉车司机模拟考试
  2. 重学 Java 设计模式:实战享元模式「基于Redis秒杀,提供活动与库存信息查询场景」
  3. python基金筛选_【量化投资工具】抓取沪深股市所有指数关联的公募基金列表(含ETF、增强、分级等)...
  4. Supermicro 1024US-TRT 服务器评测:1U 机箱中的 128 个内核
  5. Linux电脑怎么接入arm开发板,PC机与ARM开发板之间实现NFS共享
  6. 关于闰年和平年的每个月有多少天
  7. IDEA远程DEBUG
  8. 视频动作识别调研(Action Recognition)
  9. 详解SVN中trunk、branches、tag的使用
  10. speedoffice(Excel)表格中输入身份证号码显示不全怎么解决?