这里在ubuntu(相当于Linux)操作系统下实现。
选题一、信号的发送与接收 函数 kill 可以用来发送一个信号给进程,在 Linux 下可以使用 man kill 查看其使用细节。这里只讨论第(1)小题。
(1) 请使用 kill 实现发送某一个特定信号,并使用 signal 函数为上 述拟发送的信号设计一个信号处理函数改变其默认行为,要求在 UI 交互端:
①能让程序执行者获知信号接收;
②为用户提供至少 两个可选项,选择信号接收后的处理方法;
③ 没有僵死进程和异 常终止。
下面是我写的main函数。除了信号处理部分,其他都完善了
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>//Windows系统可能是用window.h头文件代替它
#include<signal.h>
#include<sys/wait.h>
void sig_handler(int sig);
void handle1();
void handle2();
int main(int argc, char **argv){
printf("--------------进入父进程------------\n");
//《深入理解计算机系统 第2版》505页的图5-25所示,信号SIGUSR1是一个用户自定义信号
signal(SIGUSR1, sig_handler); //用sig_handler函数处理 SIGUSR1 信号
int pid = fork(); //fork() 创建子进程
if(pid < 0) { //pid<0 说明子进程创建失败
fprintf(stderr, "fork failed\n");
exit(0);
} else if (pid == 0) { //pid==0 说明此时在子进程中
printf("--------------进入子进程------------\n");
pause();//停在这里等待,直到信号到达才继续
printf("--------------结束子进程------------\n");
exit(0);//子进程终止
}
kill(pid, SIGUSR1);//父进程用 kill 函数给子进程发送信号
wait(NULL);//等待子进程结束
printf("--------------结束父进程------------\n");
exit(0);
}
//这个信号处理函数我预制了2种处理方法:handle1函数 & handle2函数。当然也可以增加处理方法,
//函数结束后我直接用exit(0)终止进程了。你们也可以直接在handle1/handle2处理方法中选择终止进程,要记得加入“-----结束子进程---”那一段就好。
void sig_handler(int sig){
int choice;
printf("子进程成功收到 SIGUSR1 信号\n");
printf("输入 1,用方法1处理:在这里写入处理方法\n"); //在:后写出你要怎么处理
printf("输入 2,用方法2处理:在这里写入处理方法\n"); //在:后写出你要怎么处理
printf("请选择信号处理方法:");
Choose:
scanf("%d",&choice);
if(choice == 1){
handle1();//方法1
} else if (choice == 2) {
handle2();//方法2
} else {
printf("此选择不存在,请重新输入:");
goto Choose;
}
printf("--------------结束子进程------------\n");
exit(0);
}
//这里可以参考计算机系统实验lab4-shelllab来写
void handle1() {
printf("进入方法1\n");
printf("在这里补充代码,用来处理信号\n");
sleep(2);
printf("处理完毕\n");
return;
}
void handle2() {
printf("进入方法2\n");
printf("在这里补充代码,用来处理信号\n");
sleep(2);
printf("处理完毕\n");
return;
}