什么是信号?
信号—-signal也, 当进程收到信号后,会根据不同的信号给出不同的回应。
当信号传输给了程序,程序会先作出判断,响应它,或在忽略它。
响应:如果进程没有设置响应的handler函数,则会使用默认的
忽略:忽略信号,信号并不会消失,依然会始终在那,当忽略信号的机制消失时,依然会传给进程
signal
用来注册指定信号的行为。1
2
3
4
typedef void ( *sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
说明:
注册行为就是修改当进程接受到信号之后所作出的默认响应。
以ctrl+c 也就是SIGINT来说,当进程收到这个信号,默认是直接终止程序,
但是可以更改,所以可以发现,有的程序即使按ctrl+c也不能直接退出。
当然,更多的时候不能退出是由于系统来不及响应ctrl+c造成的。
sighandler是函数指针,这个函数的返回值也是返回函数指针值
kill
给指定pid的进程发送信号1
2
3
int kill(pid_t pid, int sig);
说明:
pid > 0 时 给指定的进程发送信号
pid == 0 时,给当前进程组的所有进程发送信号
pid == -1时,给所有pid > 1的进程发送信号
pid < 0 时,给所有属于pid绝对值进程组的进程发送信号
###alarm
指定时间用来发 SIGALRM 信号给自己1
2
3
unsigned int alarm(unsigned int seconds);
sigprocmask
设置信号的屏蔽字,指定屏蔽那些信号1
2
3
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
说明:
sigset_t 是一个结构体,有64位,每一位用来表示一个信号屏蔽状态
不能简单的用一个long来表示,因为32和64位long的大小是不一样的
对于sigset_t有特定的函数来修改它的值1
2
3
4
5
6
7
8
9
10
11
int sigempty(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int signum);
int sigdelset(sigset_t *set, int signum);
int sigismember(const sigset_t *set, int signum);
sigempty 把set结构体里面所有的屏蔽状态取消
sigfillset 把set结构体里面的所有信号都设置屏蔽
sigaddset 把set结构体里对应的signum信号设置屏蔽
sigdelset 把set结构体里对应的signum信号取消屏蔽
sigismember 判断set结构体里对应的signum信号是否为屏蔽状态
sigpending
用来查看哪些信号发送过来并且被屏蔽了。
1 |
|
当使用sigprocmask屏蔽掉某些信号之后,当信号发送过来,被屏蔽时,
使用sigpending就能找出哪些信号目前被屏蔽了
同时于sigismember函数配合使用就能一一查看哪些信号被屏蔽了
sigsuspend
临时改变屏蔽字,始程序处于挂起状态1
2
3
int sigsuspend(const sigset_t *mask);
用法主要有两种:
1 当设置了信号的屏蔽字之后,信号并不会消失,进程只是暂时不会理会这个
信号,当屏蔽字取消之后,信号就会直接发送给进程,所以呢,常常用一个
pause函数来接受这个信号。但是当屏蔽字取消之后,可能pause函数还没来的
及执行,信号就已经发送过来,这样系统就会处理这个信号,当处理完这个信号
之后,再执行pasue函数,进程就可能陷入无限的挂起当中。。。。
所以需要sigsupend函数来把还原屏蔽字和pause来封装成一个原子操作
sigaction
和signal一样,用来改变处理信号的默认方式。
1 |
|
说明:
signum用来指定进程号
act用来指定新的动作,oldact用来来保存原来的动作
struct sigaction 的结构体如下1
2
3
4
5
6
7struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};
sa_handler和sa_sigaction 都是用来指定信号的处理方式
只有使用了SA_SIGINFO标志的时候才使用sa_sigaction这个来处理信号
sigqueue
类似kill用来给指定pid的进程发送信号,但是可以发送更多信息
1 |
|