操作系统课内报告 内核编译、系统调用和进程同步通信 - 图文

2025/5/5 1:23:30

操作系统课内实验报告

分析如下:1) signal函数

上述程序中,调用函数signal()都放在一段程序的前面部位,而不是在其他接收信号处。这是因为signal()的执行起的作用只是为进程指定信号量16和17,以及分配相应的与stop()过程连接的指针。因而signal()函数必须在程序前面部分执行。

2)wait函数

在父进程中调用第1个wait(0)后,则父进程被阻塞。进入等待第一个子进程运行结束的队列,等待子进程结束。当子进程结束后,会产生一个终止状态字,系统会向父进程发出SIGCHLD信号。当接到信号后,父进程提取子进程的终止状态字,从wait()返回继续执行原程序。同样的方式,父进程继续执行第二个wait(0),并再次阻塞,等待第2个子进程运行结束。当第二个子进程运行结束后父进程继续执行剩余的语句。

3)关于exit函数

函数中每个进程退出时都用了语句exit(0),这是进程的正常终止。在正常终止时,exit()函数返回进程结束状态。进程终止时,则由系统内核产生一个代表异常终止原因的终止状态,该进程的父进程都能用wait()得到其终止状态。在子进程调用exit()后,子进程的结束状态会返回给系统内核,由内核根据状态字生成终止状态,供父进程在wait()中读取数据。若子进程结束后,父进程还没有读取子进程的终止状态,则子进程就变成了“孤儿进程”,系统进程init会自动“收养”该子进程,成为该子进程的父进程,即父进程标识号变成1,当子进程结束时,init会自动调用wait()读取子进程的遗留数据,从而避免在系统中留下大量的垃圾。

4)结果显示

上述结果中“Child process 1 is killed by parent !!”和“Child process 2 is killed by parent !!”相继出现,当运行几次后,谁在前谁在后是随机的。这是因为:从进程调度的角度看,子进程被创建后处于就绪态。此时,父进程和子进程作为两个独立的进程,共享同一个代码段,分别参加调度、执行,直至进程结束。但是谁会先被调度程序选中执行,则与系统的调度策略和系统当前的资源状态有关,是不确定的。因此,谁先从fork()函数中返回继续执行后面的语句也是不确定的。 1. 管道通信

实验结果如下:

29

操作系统课内实验报告

图3.5管道通信结果

多次实验

简要分析如下:

管道,是指用于连接一个读进程和一个写进程,以实现它们之间信息的共享文件又称pipe文件。向管道(共享文件)提供输入的发送进程(即写进程),以字符流形式将

30

操作系统课内实验报告

大量的数据送入管道;而接收管道输送的接收进程(读进程),可以从管道中接收数据。

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

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

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

判断对方是否存在。只有确定写进程和读进程都存在的情况下,才能通过管道进行通信。

二者的先后次序是随机的。

3.6实验总结

3.6.1实验中的问题与解决过程

1.编辑器不太会用,后来在网上找了资料,去图书馆借了书,看了一些,大概明白了一些。

2.程序编写方面,一些错误找了很久,经过不断调试,终于解决了。 3.一些概念不是很清楚,通过阅读相关文献有了一些大致的了解。 3.6.2实验收获

1.学习了Linux下的C语言编程流程; 2.进一步理解了进程同步互斥的概念; 3.对进程通信加深了理解。 3.6.3意见与建议

1.希望能得到更贴切的实验指导;

2.希望能进一步对Linux环境下的编程进行研究; 3.互动再多一些就好了。

3.7附件

1.软终端通信源代码:

#include

#include #include

31

操作系统课内实验报告

#include intwait_flag; void stop( ); main( ) {

int pid1, pid2; // 定义两个进程号变量 signal(3,stop); // 或者 signal(14,stop); while((pid1 = fork( )) == -1); // 若创建子进程1不成功,则空循环

if(pid1 > 0) { // 子进程创建成功,pid1为进程号 while((pid2 = fork( )) == -1); // 创建子进程2 if(pid2 > 0) { wait_flag = 1;

sleep(5); // 父进程等待5秒 kill(pid1,16); // 杀死进程1 kill(pid2,17); // 杀死进程2 wait(0); // 等待第1个子进程1结束的信号 wait(0); // 等待第2个子进程2结束的信号 printf(\ exit(0); // 父进程结束 } else {

wait_flag = 1;

signal(17,stop); // 等待进程2被杀死的中断号17 printf(\

exit(0); } } else { wait_flag = 1; signal(16,stop); // 等待进程1被杀死的中断号16 printf(\ exit(0);

} }

void stop( ) {

wait_flag = 0; }

2.管道通信源代码:

#include #include #include

int pid1,pid2; // 定义两个进程变量 main( ) { intfd[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,\ // 给Outpipe赋值 write(fd[1],OutPipe,50); // 向管道写入数据

sleep(5); // 等待读进程读出数据

32

操作系统课内实验报告

lockf(fd[1],0,0); // 解除管道的锁定 exit(0); // 结束进程1 } else {

while((pid2 = fork()) == -1); // 若进程2创建不成功,则空循环 if(pid2 == 0) { lockf(fd[1],1,0);

sprintf(OutPipe,\ write(fd[1],OutPipe,50); sleep(5);

lockf(fd[1],0,0); exit(0); } else {

wait(0); read(fd[0],InPipe,50); printf(\ wait(0); read(fd[0],InPipe,50); printf(\

exit(0); } } }

// 等待子进程1 结束 // 从管道中读出数据 // 显示读出的数据 // 等待子进程2 结束 // 父进程结束 33


操作系统课内报告 内核编译、系统调用和进程同步通信 - 图文.doc 将本文的Word文档下载到电脑
搜索更多关于: 操作系统课内报告 内核编译、系统调用和进程同步通信 - 图文 的文档
相关推荐
相关阅读
× 快捷下载通道(下载后可以自由复制和排版)

开通会员免费下载

开通会员后百万份文档资料免费自由复制和下载,是您最优的选择,赶快来试试吧!

单篇下载:10元 点击下载

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:fanwen365 QQ:370150219