系统预先定义好的某些特定的事件, 可以被发生, 也可以被接收。 发生和接收
的主体都是进程。
3.2 系统中信号的定义:
/usr/include/bits/signum.h
新内容:
1 、 信号怎样接收:
在接收信号的进程 PCB 结构中, long signal; 通过 signal 表示接收到的信号。
2 、 信号的响应方式 :
默认 忽略 自定义 ( 捕获 )
SIG_DFL SIG_IGN
0 1 | 1 |
// 修改信号的响应方式 |
typedef void (*fun_handle)(int);
fun_handle signal(int sig_num, fun_handle fun);
signal 函数修改信号的响应方式: 修改 PCB 结构中 struct sigaction 结构体数组中对应信号
值作为下标的函数指针。
int sys_signal(int signum, long handler, long res)
{
//判断信号值是否在系统的定义的范围内, 并且保证不是 SIGKILL 信号
if(signum < 1 || signum > 32 || signum == SIGKILL)
return -1;
long la = current->sigaction[signum - 1].sa_handler;//记录信号原来的响应方式
current->sigaction[signum - 1].sa_handler = (void (*)(int))handler;//修改成新的响应方式
return la;
}
修改信号的响应方式的时机? 代码中 signal 何时调用? ? ?
进程刚开始执行修改关注的信号的响应方式。 一般情况 main 函数开始第一行调用。
练习:
编写程序实现用户第一次输入 Ctrl+c 时, 输出 helloworld, 第二次输入 Ctrl+c 时, 程序结束。//见代码signal
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <signal.h>
void fun(int);
int count = 0;
void main()
{
signal(SIGINT, fun);
while(1)
{
sleep(2);
printf("main running\n");
}
}
void fun(int sign)
{
printf("hello world\n");
signal(SIGINT, SIG_DFL);
}
//第一次先写输入ctrl+c就会出现hello world不会停止要用另一个terminal ps -e|grep signal然后kill ****来杀死它
父进程不阻塞并且处理僵死进程: 子进程结束时, 会向其父进程发送一个 SIGCHLD 信
号。
结合信号处理僵死进程优势:
1、 父子进程可以并行运行。
2、 可以处理所有的僵死进程。