logo资料库

线程和进/线程管道通信实验(操作系统实验报告二).doc

第1页 / 共5页
第2页 / 共5页
第3页 / 共5页
第4页 / 共5页
第5页 / 共5页
资料共5页,全文预览结束
计算机科学与技术学院实验报告 实验题目:线程和进/线程管道通信实验 学号:XXXXXXXXXXXXX 日期:2014.3.26 班级:计算机 XXXX 班 姓名: XXXXXX 实验目的: 通过 Linux 系统中线程和管道通信机制的实验,加深对于线程控制和管道 通信概念的理解,观察和体验并发进/线程间的通信和协作的效果 ,练习利用无 名管道进行进/线程间通信的编程和调试技术。 实验要求: 设有二元函数 f(x,y) = f(x) + f(y) , (x >1) 其中: f(x) = f(x-1) * x , (x=1) f(x)=1 f(y) = f(y-1) + f(y-2) , f(y)=1 , (y> 2) (y=1,2) 编程建立 3 个并发协作进程,它们分别完成 f(x,y)、f(x)、f(y) 硬件环境: hp 计算机 处理器:Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz 2.50GHz 安装内存:4.00GB(3.85GB 可用) 软件环境:ubuntu13.10 实验步骤: 1、在声明各个存储数据所需变量后,请用户输入测试数据 2、使用 pipe()系统调用建立两个无名管道。使用 pipe 与 0 进行大小比较 来判断是否创建成功,若建立不成功程序退出,执行终止 3、使用 fork()建立第一个子进程,若 pid<0,则建立不成功程序退出,执行 终止; 4、子进程一计算 fy,并且负责从管道 1 的 1 端写入 fx。 5、父进程开始执行,再使用 fork()建立第二个子进程,若 pid<0,则建立不 成功程序退出,执行终止;
6、子进程二计算 fy,并且负责从管道 2 的 1 端写入 fy。 7、子进程二执行结束,父进程开始执行。父进程从管道 1 的 0 端,管道 2 的 0 端分别读取 fx 和 fy。计算 fxy。关闭管道,执行结束。 实现方式: 参照示例实验,使用 C 语言实现。 体会: 因为 fx 和 fy 都要和 fxy 进行通信,而二者之间不需要通信,所以建立两和 管道即可。而且,该实验进行之后无需保存管道,所以建立无名管道即可。 一个进程通过管道的一端向管道里面写入内容,另一个进程可以从这个管 道的另一端读到上一个进程写入的内容。管道是单向的。 使用 C 语言写程序对我来说依然很难,我都是基于示例实验以及别人的实验 做出来的,虽然借鉴了一些示例代码,但是我认真做了,还是很有收获的,在课 堂上学习了进程间的通信后再进行实验,理解得更透彻了。 在写程序中还是有细节没有注意到,比如在声明变量时写的是 pid1 和 pid2, 但是在程序中却把第一个子进程用 pid 表示的。诸如此类的错误出现了好多,还 是要加强细致程度。 实验结果: Please input x and y 23 14 child pid 4467 is running, now fx=862453760 (x=23) child pid 4468 is running, now fy=377 (y=14) parent pid 4466 is running, now fxy=862454137 (x=23,y=14)
分析: 用户输入测试数据(Please input x and y )以后,程序先创建了两个管道用以 fx 和 fxy 之间通信,以及 fy 和 fxy 之间通 信。然后又创建了两个进程,用以分别从管道中读取 x 和 y,并且计算 fx 和 fy, 再将 fx 和 fy 写入管道。在子进程退出前会报告其进程号和当前的 fx 或 fy 的值 (child pid 4467 is running, now fx=862453760 (x=23) ;child pid 4468 is running, now fy=377 (y=14) ) 。最后父进程执行,从管道中读取 fx 和 fy 的值,计算 fxy,然后报告其进程号 和 当 前 的 fxy 的 值 ( parent pid 4466 is running, now fxy=862454137 (x=23,y=14) )。至此,执行完成。 附录:实验程序 #include #include #include int main(int argc, char *argv[]) { int pid1,pid2;//进程号
int pipe1[2]; //存放第一个无名管道标号 int pipe2[2]; //存放第二个无名管道标号 int fx,fy,fxy;//存放计算结果 int x,y; //接受用户输入 x,y printf("Please input x and y\n"); scanf("%d %d",&x,&y); //使用 pipe()系统调用建立两个无名管道。建立不成功程序退出,执行终止 if(pipe(pipe1) < 0){ perror("pipe1 create failed"); exit(EXIT_FAILURE); } if(pipe(pipe2) < 0){ perror("pipe2 create failed"); exit(EXIT_FAILURE); } //使用 fork()建立第一个子进程,建立不成功程序退出,执行终止 if((pid1=fork()) <0){ perror("process1 create failed"); exit(EXIT_FAILURE); } if(pid1 == 0){ //第一个子进程负责从管道 1 的 1 端写,所以关闭管道 1 的 0 端 close(pipe1[0]); //计算 fx 并输出到管道 fx = Fx(x); printf("child running, fx=%d now pid %d is (x=%d) \n",getpid(),fx,x); write(pipe1[1],&fx,sizeof(int)); //读写完成后,关闭管道 1 的 1 端 close(pipe1[1]); //子进程 1 执行结束 exit(EXIT_SUCCESS); } else{ //父进程开始执行 //再创建一个子进程,建立不成功程序退出,执行终止 if((pid2=fork()) <0){ perror("process2 create failed."); exit(EXIT_FAILURE); }else if (pid2 == 0){ //子进程 2 开始执行
//管道 2 的 1 端写,所以关闭管道 2 的 0 端 close(pipe2[0]); fy = Fy(y); printf("child running, pid %d is now fy=%d (y=%d) \n",getpid(),fy,y); write(pipe2[1],&fy,sizeof(int)); close(pipe2[1]); //子进程 2 执行结束 exit(EXIT_SUCCESS); } //转回到父进程 //父进程从管道 1 的 0 端,管道 2 的 0 端读 //所以先关闭管道 1 的 1 端和管道 2 的 1 端 close(pipe1[1]); close(pipe2[1]); read(pipe1[0],&fx,sizeof(int)); read(pipe2[0],&fy,sizeof(int)); fxy = Fxy(fx,fy); printf("parent pid %d is running, now fxy=%d (x=%d,y=%d) \n",getpid(),fxy,x,y); close(pipe1[0]); close(pipe2[0]); } //父进程执行结束 return EXIT_SUCCESS; } //函数 f(xy) int Fxy(const int fx,const int fy){ return fx+fy; } //函数 f(y) int Fy(const int y){ return y==1||y==2 ? 1:(Fy(y-1)+Fy(y-2)); } //函数 f(x) int Fx(const int x){ return x==1? 1:Fx(x-1)*x; }
分享到:
收藏