lab5 Linux进程及并发程序设计 2_第1页
lab5 Linux进程及并发程序设计 2_第2页
lab5 Linux进程及并发程序设计 2_第3页
lab5 Linux进程及并发程序设计 2_第4页
lab5 Linux进程及并发程序设计 2_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、华南师范大学实验报告学生姓名 学 号 专 业 多媒体与网络技术 年级、班级 12级多媒体2班 课程名称 操作系统原理 实验项目 实验5 Linux进程及并发程序设计 实验类型 验证 设计 R 综合 实验时间 2014 年 4月22日实验指导老师 实验评分 实验5 Linux进程及并发程序设计 一实验目的:掌握Linux环境下的进程并发程序及管道应用程序的编写要点。二实验内容:1 编写一个并发程序,父进程打印“The Parent is running”,子进程打印“The Child is running”。2 编写一个并发程序,父进程打印“The Parent is running”,子进程

2、打印“The Child is running”,并保证子进程输出在前,父进程输出在后。3 编写一个管道应用程序,父进程通过管道提供字符串“put the string into the pipe.”给子进程,子进程通过管道接收这条信息,然后打印输出。4 调试并运行3.10的并发程序设计实例,显示结果是什么,并分析之。5 提高题:编写一个管道应用程序,使父进程接受用户从键盘输入的数据信息并通过管道传送给子进程,子进程打印输出通过管道接收到的数据信息。3 实验过程步骤与结果: (一)编写一个并发程序1. 根据要求编写程序:#include<stdio.h>main( ) int p;

3、 /存放子进程pid号while( ( p=fork( ) ) =-1); /创建子进程直到成功为止if (p = 0) /返回值=0表示子进程返回 printf("The Child is runningn");else /返回值>0表示父进程返回 printf("The Parent is runningn");2.存放在Linux中的bingfa.c文档中:3.使用gcc命令对bingfa.c进行编译:4.多次使用./a.out执行该命令,查看结果:输出:The Parent is runningThe Child is running或者T

4、he Child is runningThe Parent is running5. 运行结果分析:通过实验结果可看出,这是一个并发程序,子进程和父进程在不同的情况下先后出现的顺序可能不同,具有随机性。(2) 编写一个并发程序(子先父后)1. 根据要求编写程序:#include<stdio.h>#include <stdlibh>main( ) int p; /存放子进程pid号while( ( p=fork( ) ) =-1); /创建子进程直到成功为止if (p = 0) /返回值=0表示子进程返回 printf("The Child is running

5、n"); exit(0); / 在子进程结束时调用exit(0),使子进程自我终止,并发终止信号给其父进程;else /返回值>0表示父进程返回 wait(0); /父进程等待子进程终止,再执行下方程序 printf("The Parent is runningn"); 2. 存放在Linux中的Childfirst.c文档中:3. 使用gcc命令对Childfirst.c进行编译:4.多次使用./a.out执行该命令,查看结果:输出:The Child is runningThe Parent is running5. 运行结果分析:从运行结果可看出此程序

6、实现了父等子的功能,始终是子进程先执行。从代码上看,是用wait(0)和exit(0)实现的,在子进程(p=0)运行后使用exit(0)终止进程,在父进程(p>0)内容程序执行前加上wait(0),使父进程接收到子进程结束的信号后才执行内容程序,从而实现了后执行父进程的效果。(3) 编写一个管道应用程序(父提供给子字符串)1. 根据要求编写程序:#include <sys/types.h>#include <unistd.h>#include <stdio.h> /printf函数的头文件#include<stdlib.h> /exit函数

7、的头文件#define LINESIZE 1024int main(void) int n, fd2; pid_t pid; char lineLINESIZE; if(pipe(fd)<0) /调用pipe()函数建立管道; printf("pipe error"); /建立不成功则返回“pipe error",并退出; exit(1); if(pid=fork()<0) /创建进程,创建不成功则返回"fork error"并退出 printf("fork error"); exit(1); else if(p

8、id>0) /父进程的fork()返回 close(fd0); /关闭管道读指针; printf("I'm fathern"); /声明它是父进程 write(fd1, "put the string into the pipe.n",29);/将"put the string into the pipe.n"写入管道 close(fd1); /关闭管道写指针; else /父进程的fork()返回 close(fd1); /关闭管道写指针; printf("I'm sonn"); /声明它是

9、子进程 n=read(fd0,line, LINESIZE);/读取输入的信息,存放到字符串line中 printf("string: %sn", line); /输出”string:“和输入的信息 close(fd0); /关闭管道读指针; exit(0); /退出程序;2. 存放在Linux中的father_to_son.c文档中:3. 使用gcc命令对father_to_son.c进行编译:4. 使用./a.out执行该命令,查看结果:输出:I'm fatherI'm sonstring:put the string into the pipe.5.运

10、行结果及程序思路分析:通过pipe()函数建立管道;用close(fd0)关闭父进程管道读指针,利用write(fd1, "字符串内容",字符串长度);写入字符串,最后关闭管道写指针;用close(fd1)关闭子进程管道写指针,利用read(fd0, "字符串内容",字符串长度);读取管道中字符串,最后关闭管道读指针;实现父进程向子进程传递字符串的功能;(四)调试运行3.10并发程序并进行分析1.程序源代码如下:【father1.c】:【child1.c】:【pipeline.c】:2.执行程序:输入: cc -o child1 child1.c cc

11、-o father1 father1.ccc pipeline.c./a.out 输出:_Parent is using pipe write.child,child.3. 代码与运行结果分析:【father1.c】:#include<stdio.h>#include<stdlib.h>main()static char string="Parent is using pipe write."int len;len=sizeof(string);write(1,string,len); /将"Parent is using pipe wri

12、te."写入字符串len中printf("parent,parent, parentnnn"); /输出显示是parent进程在执行exit(0);【child1.c】:#include<stdio.h>main()char output30;read(0,output,30); /读output中的内容printf("_%sn child,child.n",output);/输出output中的内容加上child,child声明是子进程return(0);【pipeline.c】:#include<stdio.h>#i

13、nclude<stdlib.h>#include<unistd.h>#define STD_INPUT 0 /定义标准输入设备描述符#define STD_OUTPUT 1 /定义标准输出设备描述符int fd2;main() static char process1="father1",process2="child1" pipe(fd); /定义管道,返回文件描述符fd0,fd1 pipeline(process1,process2); /调用自定义函数pipeline(); exit(1); /程序结束pipeline(pr

14、ocess1,process2)char *process1,*process2; int i; while(i=fork()=-1); /创建进程,创建失败则反复创建,直到创建成功 if(i) /父进程的fork()返回 close(fd0); /关闭管道读端 close(STD_OUTPUT); /关闭标准输出描述符1(原来是写到显示器的指针) dup(fd1); /指定标准输出描述符1为管道写指针,语句后调用printf函数,那么内容并不会输出到显示器,而是写入了管道中。 close(fd1); /关闭原始管道写指针 execl(process1,process1,0); /用程序fat

15、her1覆盖当前程序 printf("father failed.n");/execl()执行失败时才执行这一行 else close(fd1); /关闭管道写端 close(STD_INPUT); /关闭标准输出描述符0 dup(fd0); /指定标准输入描述符0为管道读指针, 语句后调用scanf函数,那么不会从键盘读取内容,而是从管道中读取。 close(fd0); /关闭原始管道读指针 execl(process2,process2,0); /用程序child1覆盖当前程序 printf("child failed.n");/execl()执行失

16、败时才执行这一行 exit(2); /程序结束4. 运行结果分析:输出结果为:_Parent is using pipe write.child,child. Pipeline.c中调用了dup(fd1); 指定标准输出描述符1为管道写指针,语句后调用printf函数,那么内容并不会输出到显示器,而是写入了管道中。而从结果可看出,父进程通过管道传给了子进程“Parent is using pipe write.”(从而才会前面有_,后面有child,child),同时pipeline.c中使用execl(process1,process1,0); 用父进程覆盖原进程,如果没有发挥dup(fd1

17、)的作用(将printf中的内容“parent,parent,parent”写入管道中),也应在界面中打印出来。所以我进行了以下几个测试:(1) 测试printf是否因write而没有输入到管道中(注释掉write行)输出了:_parent,parent,parent(3行)child,child出现了“_”和“child,child”,说明dup(fd1)的作用实现了,prinf的内容的确输入到管道中。说明是write导致的。(2) 测试是否由于write和printf的顺序导致无法写入(调换位置)仍然无法输出,说明不是顺序问题;(3) 测试是否发送接收字符串的问题(是否结束符0的问题)修改

18、发送字符串长度:后面出现的pa说明的确是字符串长度的问题;接下来修改接收字符串长度:成功实现prinf内容输入管道并从子进程同时读取出用write和prinf写入的内容。分析字符串长度为何会导致这种问题:通过上网了解到,用sizeof计算变量的空间大小时,它会把数组末尾的0符号也计算进去,在你往管道内输入后,读取时遇见'0'符号就会认为字符串结束,就不再读取prinf中的内容,而prinf中的内容,不管与write命令的顺序如何,都只会把内容输入到管道中write的部分。从而,整个程序利用execl();实现father1和child1在同一程序中实现,father1通过管道通

19、信传给了child1字符串;同时利用close(fd)的方式实现进程的互斥。使用dup(fd)实现将外部输入输出设备的信息置于管道中,进行读取。(五)编写一个管道应用程序(父接收键盘输入传给子进程)1.根据要求编写程序:#include <sys/types.h>#include <unistd.h>#include <stdio.h>#include <signal.h>#include <stdarg.h>#include<stdlib.h>#define LINESIZE 1024int main(void) int

20、 n, fd2; pid_t pid; char lineLINESIZE; fgets(line, sizeof(line), stdin); /获得键盘输入,存放在字符串line中 if(pipe(fd)<0) /调用pipe()函数建立管道; printf("pipe error"); /建立不成功则返回“pipe error",并退出; exit(1); if(pid=fork()<0) /创建进程,创建不成功则返回"fork error"并退出 printf("fork error"); exit(1)

21、; else if(pid>0) close(fd0); /关闭管道读指针 printf("I'm fathern"); /声明它是父进程 write(fd1, line,sizeof(line); /将line中的内容(即键盘输入)写入管道中 close(fd1); /关闭管道写指针 else /子进程的fork()返回 close(fd1); /关闭管道写指针; printf("I'm sonn"); /声明它是子进程 n=read(fd0,line, LINESIZE);/读取输入的信息,存放到字符串line中 printf("string: %sn", line); /输出”string:“和输入的信息 close(fd0); /关闭管道读指针 exit(0); /退出程序;2.存放在Linu

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论