《实验6进程及进程间通信之共享内存》由会员分享,可在线阅读,更多相关《实验6进程及进程间通信之共享内存(16页珍藏版)》请在金锄头文库上搜索。
1、实验6进程及进程间的通信实验目的:1、 理解进程的概念2、掌握进程复制函数fork的用法3、掌握替换进程映像exec函数族4、掌握进程间的通信机制,包括:有名管道、无名管道、 信号、共享内存、信号量和消息队列实验要求:熟练使用该节所介绍fork函数、exec函数族、以及进程间通 信的相关函数。实验器材:软件:Ubu nt 的 vmware虚 拟机硬件:PC机一台实验步骤:1、用进程相关API函数编程一个程序,使之产生一个进程扇:父进程产生一系列子进程,每个子进程打印自己的PID然 后退出。要求父进程最后打印 PID。参考代码如下:#include #include tinclude # ind
2、u-de int ma in (int argc , cha.r const *argv 1) int 1r n;scanf ( y in);prdt a fork(;/父进程if (a 4/子进程else if(apiint f ( 11 PI D :PPID: %d.n n , getpicl ( ) r getppid ();exit(0);wait. (NULL);print f (,TEI 匚;nIr j g&tpidf f getppidO ) rreturn ;2、用进程相关API函数编写一个程序,使之产生一个进程链:父进程派生一个子进程后,然后打印出自己的PID,然后退出,该子
3、进程继续派生子进程,然后打印PID,然后退出,以此类推。要求:1)实现一个父进程要比子进程先打印 PID的版本。(即 打印的PID 一般是递增的)2 )实现一个子进程要比父进程先打印PID的版本。(即打印的PID一般是递减的)打印PID进程链1,process_chai nl.c的参考代码如下:ttinclude4fxnclu.de UiTiclude #xnclude unls七d.hint iu-x口fin匸 n匚吕匚 chn匚 cojist *曰工勺矿J, 3(ic匸 i j a;scanf ( *d ,T r &n): for( ; g&tppid ()7pid_t a = fork(
4、);/父进程,该千的都千完的,功德圆淸,走人!if(a 0)耳|(eiELt ();-J/子进程,循环执行跟父送程完全一样的代码.eJs i(a = C)臼csontinuLe ;return进程链2的参考代码如下:fri ncludei nclude tinclude tincludeint main(int argc, char const *argv) Bint i( n;scanf ( d f finj *for ( j_= J ;f +) C)getppidO );/等待子进程完成之后,打印FHD和FF5 wit(NULL);printf ( FID: %df PFID:t getp
5、id () f/功铠圆淸,走人!exit(|r/子进程m循环执行跟父进程充全一樟的代码=else if(a = C)acntinue;return ;3、编写程序execl.c,实现父进程打印自己的pid号,子进程调用execl函数,用可执行程序替换本进程。注意命令行参数。 参考代码如下:/*execl.c*/#i ncludevu ni std.h#in clude#in cludeint main(int argc,char *argv)/* 判断入参有没有传入文件名 */if(argc0)printf( “I m parent,my pid:%d,mysun spid %dn ”,get
6、pid(), result);/* 下面代码是调用 ls 程序 , 用可执行程序 ls 替换本进程 if(result=0)printf( “I m sumprocess my pid is %d n”,getpid();if(execl(/bin/ls,ls,-l,NULL)0)perror(execlp error);*/* 下面程序调用 execl 函数,用可执行程序替换本进程 */ if(result=0)printf( “ I m sum process my pid is %dn ” ,getpid(); if(execl(./,argv1,NULL)0) perror(execl
7、 error!);其中的 代码如下:#include #include #include #include #include void create_ *)/* 创建的文件具有可读可写的属性 */ if(creat()0) printf(create failure!n,); exit(EXIT_FAILURE);else printf(create success!n,);int main(int argc,char *argv)/* 判断入参有没有传入文件名 */ if(argc2)again!n); perror(you havent input the try exit(EXIT_FA
8、ILURE);create);exit(EXIT_SUCCESS);代码分析execl函数会让一个可执行程序运行并替换本进程,那么这个可执行程序就应该有创建一个文件的功能。我们可以用编译 产生的可执行文件来作为该可执行程序。运行步骤:1)命令:gcc execl.c - o execlgcc o(rootXocalhcs七 2-2-3# Isexecl.c fil_cxeat.cro0tlocalhst 22-3# gcc xcl-0 eeclzootlocalhos七 2-2-3 # gcc file_creat tc -o file_ci:eatxootlocalhost 2-2-3# I
9、sexecl execl.c file creat file creat.ctootlocalhost 2-2-3#2)运行应用程序可以看到运行程序后,创建了新的文件“ file ”夕 rootfflDGahostMmMhgfc/retiSjsh理axteJE空口 1 百蓉一rootlocalhost 2-2*3| Isexecl execl,c file_cr*t flle_creat,crootlocalhost 2*2-3#filecreat file f11q success frootslocalhost 2-2-3J # Isexecl execl .c filef ile_cre
10、at .croGtlocAlhcst 2-2-3J#3).总结:exec函数族会在一个进程中启动另一个程序执行。并用它来 取代原调用进程的数据段、代码段和堆栈段。在执行完exec函数调用后,原调用进程的内容除了进程号之外,其他全部 被新的进程替换了。4、execlp函数实例:/*execlp.c*/#include#include#includeint main()pid_t result;result=fork();if(result=0)if(execlp(ls,ls,-l,NULL)0)perror(execlp error);代码分析:使用 execlp 函数可以省略指定 ls 的路径
11、,因为 ls 程序在 path 路径中。 execlp 函数会到 path 路径中找到可 执行程序。5、execv 函数实例 :/*execv.c*/#include#include#includeint main()pid_t result;char *arg=ls,-l,NULL;result=fork();if(result=0)if(execv(/bin/ls,arg)0)perror(execlp error);代码分析,execv函数将可执行程序的运行参数放到数组 *arg中。6、无名管道实验:用命令行敲入命令:farsightub un tu-desktop:$ Is -l |
12、wc -w 运用所学知识,编程实现上述命令的效果。参考代码如下:ftinc lu.de- include u耳七dlibh#xiicXudexng .4nc lu.de in- maiin (int ougu * chair uount *a rgr ff摘一-卜无名管道int d 1 ;pipe(fd): pidt 2 = fork(J;/父进程i(= c(/将管道的写端珀【叮覆盖丄号立件描述符,德得丄号文件推述符/也珀【口一樺代裘了晉進的写端而不是标椎輸由) dup2(dl r 1);/关担没用的文件持述符close(fd 1 );close(fd:;/执dTlsfFff令,此时丄9命令的输出结果就会被辅送到管It不是标世输出)CKCClpf 1= ,NVRL) f/子選程if (a =)/将管道的渎端岀21覆盖0号文件描述符,便得0号文坪捲述符/也跟fdO-样,吒表了管道的渎端(而不是标進输入) dup2(fdD , C);.7关掉没用的文