操作系统实验二之信号处理实验
来源:互联网 发布:中国城镇住户调查数据 编辑:程序博客网 时间:2024/06/06 03:42
一、题目
1、编制一段程序,使用系统调用fork()创建两个子程序,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即按Ctrl C键),当捕捉到中断信号后,父进程调用kill()向两个子进程发出信号,子进程捕捉到信号后,分别输出下面信息后终止:child process 1 is killed by parent!child process 2 is killed by parent!父进程等待两个子进程终止后,输出以下信息后终止:parent process is killed!
2、在上述的程序中增加语句signal(SIGINT, SIG_IGN)和signal(SIGQUIT, SIG_IGN),观察执行结果并分析原因。这里signal(SIGINT, SIG_IGN)和signal(SIGQUIT, SIG_IGN)分别为忽略“Ctrl Z”键信号以及忽略“Ctrl C”中断信号。
二、实验过程及分析
要想做好这个实验,需要先学习一下关于linux下系统信号的基础知识。推荐下面两篇文章:
1. Linux 进程间通信 — 信号通信 — signal — signal(SIGINT, my_func); — 按键驱动异步通知
2. linux 捕获kill命令的信号
小实验一
1. 设计流程
2. 代码
#include<stdio.h>#include<stdlib.h>#include<signal.h>#include<unistd.h>void waiting();void stop();void alarming();int wait_mark;void main(){ int pid1, pid2; while((pid1 = fork()) == -1);//创建子进程1 if(pid1 > 0 ){//如果是父进程 while((pid2 = fork()) == -1);//创建子进程2 if(pid2 > 0){//如果是父进程 wait_mark = 1;//等待状态为1,等待中断信号 signal(SIGINT,stop);//设置收到信号ctrl+C时,执行stop函数 signal(SIGALRM,alarming);//设置收到SIGALRM(时钟)信号,则执行alarming函数 waiting();//休眠5秒 kill(pid1, 16);//向进程1发出信号16 kill(pid2, 17);//向进程2发出信号17 wait(0);//等待进程执行结束,同步 wait(0);//等待进程执行结束,同步 printf("parent precess is killed!\n"); exit(0);//退出进程 } else{ wait_mark = 1;//等待中断信号 signal(17,stop);//设置收到中断信号17,执行stop函数 //signal(SIGINT,SIG_IGN);//设置收到ctrl+c时,忽略该信号 while(wait_mark != 0); lockf(1,1,0);//加锁 printf("child process2 is killed by parent!\n"); lockf(1,0,0);//解锁 exit(0); } } else{ wait_mark = 1; signal(16,stop);设置收到中断信号16,执行stop函数 //signal(SIGINT,SIG_IGN);设置收到ctrl+c时,忽略该信号 while(wait_mark != 0); lockf(1,1,0);//加锁 printf("child process1 is killed by parent!\n"); lockf(1,0,0);//解锁 exit(0); }}void waiting(){ sleep(5);//休眠 if(wait_mark != 0) kill(getpid(), SIGALRM);//向当前进程发出中断信号}void alarming(){ wait_mark = 0;}void stop(){ wait_mark = 0;}
结果
若按下ctrl+c,立即终止程序,并且只会输出“parent process is killed!”;若未按下ctrl+c,则过了5秒后,自动终止程序,输出如上图。
小实验二
代码
#include<stdio.h>#include<stdlib.h>#include<signal.h>#include<unistd.h>void waiting();void stop();int wait_mark;void main(){ int pid1, pid2; while((pid1 = fork()) == -1); if(pid1 > 0){ while((pid2 = fork()) == -1); if(pid2 > 0){ wait_mark = 1;//进入等待状态 signal(SIGINT,stop); //接收到信号,执行stop waiting();//等待 sleep(1);//休眠1秒 kill(p1, 16);//向进程1发送信号16 sleep(1); kill(p2, 17);//向进程2发送信号17 wait(0); wait(0); printf("parent process is killed!\n");//输出 exit(0);//进程终止 } else{ signal(SIGINT,SIG_IGN); //忽略ctrl+c signal(SIGQUIT,SIG_IGN);//忽略ctrl+z signal(17,stop); //接收父进程发送的信号 wait_mark=1;//等待中断 waiting();//等该父进程发送终止信号信号 lockf(1,1,0); //加锁 printf("child process 2 is killed by parent!\n"); lockf(1,0,0);//解锁 exit(0); //进程终止 } } else{ signal(SIGINT,SIG_IGN); //忽略ctrl+c signal(SIGQUIT,SIG_IGN);//忽略ctrl+z signal(16,stop); //接收父进程发送的信号 wait_mark=1;//等待中断 waiting();//等该父进程发送终止信号信号 lockf(1,1,0); //加锁 printf("child process 1 is killed by parent!\n"); lockf(1,0,0);//解锁 exit(0); //进程终止 }}void waiting(){ while(wait_mark != 0);}void sotp(){ wait_mark = 0;}
结果
输出如上图。
分析
两个实验程序的区别在于:
第一个程序中,三个进程都可以收到SIGINT信号,所以如果按下ctrl+c,两个子进程会立即结束;而父进程中由于修改了SIGINT信号的默认响应方式,所以会正常运行结束。最终输出了“parent process is killed!”。
第二个程序中,三个进程同样都可以接收到SIGINT信号,但是只有父进程响应了该信号,而子进程接收到该信号后,会忽它。因此,按下ctrl+c后,父进程向两个子进程发出kill信号,最终会输出图示结果并结束运行。
附:ctrl+c, ctrl+z信号说明
▶ctrl+c:发送 SIGINT 信号给前台进程组中的所有进程,常用于终止正在运行的程序。
▶ctrl+z:发送 SIGTSTP 信号给前台进程组中的所有进程,常用于挂起一个程序。
- 操作系统实验二之信号处理实验
- 操作系统实验二之管道通信实验
- 华师 操作系统实验 实验二
- 操作系统实验二实验报告
- 操作系统实验二
- 进程通信之(一,二) 信号机制实验
- 数字信号处理实验(二)
- 数字图像处理实验(二)
- 操作系统实验二 作业调度
- 操作系统实验二 进程管理
- 操作系统实验一之进程控制实验
- 操作系统实验四之进程同步实验
- 操作系统实验六之死锁问题实验
- 操作系统实验之银行家算法
- 操作系统实验之系统调用
- 操作系统实验之进程管理
- 操作系统实验之处理机调度
- 操作系统实验之磁盘调度
- java面试题总结
- 解决xcode printf 无输出
- 做安全的,这里有你意想不到的东西
- linux 终端打印内容输出到文件
- web 前端面试题个人总结
- 操作系统实验二之信号处理实验
- 快速排序复杂度
- c语言结构体大小
- EOJ
- swift闪屏页
- struts2笔记
- astyle代码格式化工具
- MFC消息处理学习总结
- vue-resource HTTP API基础