signal基础

signal

man 7 signal

1.kill -l 显示所有信号

kill -signal PID

killall -signal name

2.产生信号

ctrl+c => SIGINT

ctrl+\ => SIGQUIT

ctrl+z => SIGTSTP

信号9(SIGKILL),19(SIGSTOP)不能被阻塞(进程中可屏蔽两信号sigaddset()不报错,但不起作用),不能被忽略,也不能注册信号处理函数(直接报错)。

信号共计SIGRTMAX个,其中32,33无信号,

if(sigi == SIGKILL || sigi == SIGSTOP || sigi == 32 || sigi == 33)

kill命令默认发送信号15(SIGTERM)。

3.系统默认信号处理方式

  • linux对每种信号都规定了默认动作,具体可参考man 7 signal
  • SIGCHLD 忽略
  • 实时信号的缺省反应是结束进程。
  • 如果不想程序采用默认动作处理进程,需要捕捉函数(为想要特殊处理的函数指定信号处理函数)。如发生SIGALARM或SIGPIPE,进行超时处理即可,不必终止进程。此外若想发生信号时做特殊处理也应指定信号处理函数,如发生段错误时,提示用户等。

4.操作函数

  • kill

#include <signal.h>

int kill(pid_t pid, int signo);

  • raise自发信号

int raise(int signo);

  • abort 自发SIGABRT信号,终止

void abort(void);

  • alarm闹钟

unsigned int alarm(unsigned int sec);

原来没有调度alarm返回0或以前设定的闹钟时间还剩多少秒。如果sec为0,表示取消以前设定的闹钟,返回剩余的秒数。

5.阻塞信号集函数

每个进程都有一个用来描述哪些信号递送到进程时将被阻塞的信号集,该信号集中所有信号在递送到进程后都将被阻塞。

阻塞信号集也叫当前进程的信号屏蔽字(signal Mask)。

#include <signal>

int sigemptyset(sigset_t *set);置0

int sigfillset(sigset_t *set);置1

int sigaddset(sigset_t *set, int signum);某位置1

int sigdelset(sigset_t *set, int signum);某位置0

成功0,失败-1.

int sigismember(const sigset_t *set, int signum);

包含该位返回1,不包含返回0,错误返回-1.

6.信号集函数

int sigpromask(int how, const sigset_t *set, sigset_t *oset);

成功返回0,失败返回-1;

how:SIG_BLOCK +, SIG_UNBLOCK -, SIG_SETMASK.

int sigpending(sigset_t *set);

读取未决信号集。

成功0,失败-1。

注:实际执行信号的处理动作称为信号递达(Delivery);未决(信号从产生到递达之间)。

int pause(void);

pause函数使调用进程挂起直到有信号递达。信号的处理动作是终止进程,则进程终止,pause不能返回;忽略,则进程处于挂起状态,pause不返回;捕抓,则调用信号处理函数后pause返回-1,errno置为EINTR。

pause只有出错的返回值。

int sigsuspend(const sigset_t *sigmask);

和pause一样,无成功返回值。

只有执行了一个信号处理函数后,sigsuspend才返回,返回-1,errno置为EINTR。

注:sigsuspend临时用sigmask取代信号屏蔽字,挂起进程。调用sigsuspend时应将想获取的信号从原来的信号屏蔽子中移除填充到sigmask中。

可参考:

http://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index1.html

http://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index2.html

上一篇:Linux Kill 无法关闭进程


下一篇:ps -ef|grep详解 、kill与kill -9的区别