好文档 - 专业文书写作范文服务资料分享网站

操作系统实验 - 进程通信

天下 分享 时间: 加入收藏 我要投稿 点赞

四、 实验过程、步骤及内容 1、编写程序:用 fork( )创建两个子进程,再用系统调用 signal( )让父进程捕捉键盘上来的中断信号(即按^c 键);捕捉到中断信号后,父进程用系统调用 kill( )向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止: Child process1 is killed by parent! Child process2 is killed by parent! 父进程等待两个子进程终止后,输出如下的信息后终止: Parent process is killed! 2、分析利用软中断通信实现进程同步的机理编写程序实现进程的管道通信。用系统调用 pipe( )建立一管道,二个子进程 P1 和 P2分别向管道各写一句话: Child 1 is sending a message! Child 2 is sending a message! 父进程从管道中读出二个来自子进程的信息并显示(要求先接收 P1,后 P2)。 3、消息的创建、发送和接收。使用系统调用 msgget( ),msgsnd( ),msgrev( ),及 msgctl( )编制一长度为1k 的消息发送和接收的程序。 ( 一) 信号机制实验参考代码 #include #include #include void waiting( ),stop( ); int wait_mark; main( ) { int p1,p2,stdout; while((p1=fork( ))= =-1); /*创建子进程 p1*/ if (p1>0) { while((p2=fork( ))= =-1); /*创建子进程 p2*/ if(p2>0) { wait_mark=1; signal(SIGINT,stop); /*接收到^c 信号,转 stop*/ waiting( ); //如无按键将等待 kill(p1,16); /*向 p1 发软中断信号 16*/ kill(p2,17); /*向 p2 发软中断信号 17*/ wait(0); /*同步等待子进程结束*/ wait(0); printf(\exit(0);//退出进程 } else { wait_mark=1; signal(SIGINT, SIG_IGN); /* 设置信号函数处理方式,当收到键 盘发设置信号函数处理方式,当收到键盘发 送键盘中断(如 break 键被按下)信号

时将会忽略此信号。 */ signal(17,stop); /*接收到软中断信号 17,转 stop接受父进程发送信号*/ waiting( ); lockf(stdout,1,0); printf(\lockf(stdout,0,0); exit(0); } } else { wait_mark=1; signal(16,stop); /*接收到软中断信号 16,转 stop*/ waiting( ); lockf(stdout,1,0); printf(\lockf(stdout,0,0); exit(0); } } void waiting( ) { while(wait_mark!=0);//通过循环使子进程停止 } void stop( ) { wait_mark=0;//使子进程继续运行 } (二)进程的管道通信实验参考代码: #include #include #include int pid1,pid2; main( ) { int fd[2]; char outpipe[100],inpipe[100]; pipe(fd); /*创建一个管道*/ while ((pid1=fork( ))= =-1); if(pid1= =0) { lockf(fd[1],1,0); sprintf(outpipe,\把串放入数组 outpipe 中*/ write(fd[1],outpipe,50); /*向管道写长为 50 字节的串*/

sleep(5); /*自我阻塞 5 秒*/ lockf(fd[1],0,0); exit(0); } else { while((pid2=fork( ))= =-1); 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); /*从管道中读长为 50 字节的串*/ printf(\wait(0); read(fd[0],inpipe,50); printf(\exit(0); } } } (三)消息机制参考代码: 1、client.c #include #include #include #define MSGKEY 75 struct msgform { long mtype; char mtext[1000]; }msg; int msgqid; void client() { int i; msgqid=msgget(MSGKEY,0777); /*打开 75#消息队列*/ for(i=10;i>=1;i--) { msg.mtype=i;

printf(“(client)sent\\n”); msgsnd(msgqid,&msg,1024,0); /*发送消息*/ } exit(0); } main( ) { client( ); } 2、server.c #include #include #include #define MSGKEY 75 struct msgform { long mtype; char mtext[1000]; }msg; int msgqid; void server( ) { msgqid=msgget(MSGKEY,0777|IPC_CREAT); /*创建 75#消息队列*/ do { msgrcv(msgqid,&msg,1030,0,0); /*接收消息*/ printf(“(server)received\\n”); } while(msg.mtype!=1); msgctl(msgqid,IPC_RMID,0); /*删除消息队列,归还资源*/ exit(0); } main( ) { server( ); } 错误分析 信号机制程序中,signal( )都放在一段程序的前面部位,而不是在其他接收信号处。这是因为 signal( )的执行只是为进程指定信号值 16 或 17 的作用,以及分配相应的与 stop( )过程链接的指针。因而,signal( )函数必须在程序前面部分执行。 本方法通信效率低,当通信数据量较大时一般不用此法。当你 Ctrl-c 的时候,系统会给父进程及其两个子进程都发送 SIGINT 信号 (对 bash 来说,这三个进程都是前台进程,所以都发送 ) ,对于父进程来说,收到这个信号自然是调用,对于父进程来说,收 到这个信号自然是调用 stop 函数了,但是对于两个子进程来说,默认的对这个信号的处理就是退出函数了,但是对于两个子进程来说,默认的对这个信号的处理就是退出 (exit) ,

所以你看不到子进程的打印。 进程接收到信号以后,可以有如下 3 种选择进行处理: 1) 接收默认处理:接收默认处理的进程通常会导致进程本身消亡。例如连接到终端的进程,用户按下 CTRL+c,将导致内核向进程发送一个 SIGINT 的信号,进程如果不对该信号做特殊的处理,系统将采用默认的方式处理该信号,即终止进程的执行; 2)忽略信号:进程可以通过代码,显示地忽略某个信号的处理,例如:signal(SIGINT,SIGDEF);但是某些信号是不能被忽略的。 3)捕捉信号并处理:进程可以事先注册信号处理函数,当接收到信号时,由信号处理函数自动捕捉并且处理信号。 从理想的结果来说,应当是每当 client 发送一个消息后,server 接收该消息,client 再发送下一条。也就是说“(client)sent”和 “(server)received”的字样应该在屏幕上交替出现。 实际的结果大多是,先由 client 发送了两条消息,然后 server 接收一条消息。此后 client 、server 交替发送和接收消息。最后 server 一次接收两条消息。client 和 server 分别发送和接收了 10 条消息,与预期设想一致。

操作系统实验 - 进程通信

四、实验过程、步骤及内容1、编写程序:用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即按^c键);捕捉到中断信号后,父进程用系统调用kill()向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止:Childprocess1iskilledbyparent!Childprocess2is
推荐度:
点击下载文档文档为doc格式
6x0um128mt41z4g1sgcd5uqa87qzsz016oo
领取福利

微信扫码领取福利

微信扫码分享