操作系统实验报告
实验名称
班 级 学 号 姓 名
实验三: 进程的管道通信
物联网1201班 20124052 李垠桥
一. 实验目的 加深对进程概念的理解,明确进程和程序的区别。学习进程创建的过程,进一步认识进程并发执行的实质。分析进程争用资源的现象,学习解决进程互斥的方法。学习解决进程同步的方法。掌握Linux系统中进程间通过管道通信的具体实现。 二. 实验内容及要求 1. 实验内容 使用系统调用pipe()建立一条管道,系统调用fork()分别创建两个子进程,它们分别向管道写一句话,如:
Child process1 is sending a message! Child process2 is sending a message!
父进程分别从管道读出来自两个子进程的信息,显示在屏幕上。 2. 实验要求 (1) 这是一个设计型实验,要求自行、独立编制程序。 (2) 两个子进程要并发执行。 (3) 实现管道的互斥使用。当一个子进程正在对管道进行写操作时,另一个欲写入管道的子进程必须等待。 使用系统调用lockf(fd[1],1,0)实现对管道的加锁操作,用lockf(fd[1],0,0)解除对管道的锁定。 (4) 实现父子进程的同步,当父进程试图从一空管道中读取数据时,便进入等待状态,直到子进程将数据写入管道返回后,才将其唤醒。 三. 程序流程图 1. 主函数 (main):
START建立管道失败TRUE输出建立管道失败FALSE提示输入进程数量并等待,调用createProgress函数END
2. 创建进程函数函数 (createProgress)
START进程计数还没减到0TRUE创建子进程失败TRUEFALSE提示创建子进程失败FALSETRUE处于子进程FALSE处于父进程TRUETRUE调用createProgress函数进程计数还没减到0FALSEFALSEFORTRUE父进程进入阻塞状态,直到子进FALSE程执行结束后从管道中读出END
四. 程序源代码、文档注释及文字说明 1. 程序语言:c语言 2. 源代码:
#include
int preNum;
int fields[2];//管道两端 char input[100]; char output[100];
int main() { }
int createProgress(int num) {
pid_t pid; if(num--!=0) {
while((pid=fork())<0) { }
if(pid==0)//当前为子进程 { }
else if(pid>0)//当前为父进程 {
if(num!=0) { } else {
createProgress(num);
printf(\生成了子进程,PID:%d\\n\lockf(fields[1],1,0);//锁住写端口 sprintf(input,\:%d\\n\write(fields[1],input,sizeof(input)); lockf(fields[1],0,0);//解锁写端口 exit(0);
printf(\生成子进程失败!\\n\
while(pipe(fields)!=0)//建立管道,失败退出 { }
printf(\清输入进程数量:\scanf(\createProgress(preNum); return 0;
printf(\生成管道失败!\\n\
}
}
}
}
int i=0;
for(;i wait(0);//父进程进入阻塞状态,直到子进程执行结束 printf(\当前为父进程,PID:%d\\n\read(fields[0],output,100); printf(\父进程从管道中读到的数据为:%s\\n\ 五. 运行结果及其说明 六. 程序使用说明 本程序不仅限于一个父进程,两个子进程,提供了手动输入生成子进程的功能,如图1所示。 图形 1 请输入子进程数量 七. 问题 1. 进程与两个子进程并发执行的顺序,并说明原因。 (1) 父进程调用fork函数产生子进程1 (2) 父进程调用fork函数产生子进程2 (3) 父进程调用wait函数等待子进程结束 (4) 某一个子进程结束,激活父进程 (5) 父进程执行,调用wait函数等待剩余的子进程结束 (6) 另一个子进程结束,激活父进程 (7) 父进程执行,程序执行结束 2. 若不对管道加以互斥控制,会有什么后果? 管道进行互斥控制,是为防止两个子进程对管道资源进行争夺而产生信息丢失或覆盖。如果不加控制,那么可能一个子进程写入的信息还没来得及被父进程读出,另一个子进程又