1. 文章参考APUE第10章
kill在*nux族中主要代表两类,一是在函数内部调用的kill函数,用于给其他进程发送signal。
(函数原型 int kill(pid_t pid, int sig);)
二是在Shell执行的kill命令,用于给后台进程发送信号。(参考这里)
至于9是什么,在*unix中,signal是一组整数。
参考这个头文件
例如:
#define SIGKILL 9
#define SIGUSR1 10
#define SIGUSR2 12
#define SIGSTOP 19
上面代码展示的几个值是比较关键的。我们继续来谈。
聊完了kill, 就有必要知道程序是怎么处理信号的,因为是特别篇所以我懒得讲到中断什么的。。这里就讲一下怎么用signal覆盖或者无视中断。
程序调用signal()函数来自定义对信号的处理,他的原型是: void (*signal(int signo, void (*func)(int)))(int);
这个原型比较复杂,推荐把他看懂。 (看不懂参考这里)
简单介绍一下。 首先我们看到 signal, 他的左边是(),右边是*, 说明他是一个返回*号的函数,参数是()里面的东西。
然后跳出 signal所在的括号看,void ()(int) 眼熟么,就像void (*p) (int) ,这是一个指向函数的指针,函数的参数是int。如此以来,signal返回的是一个指向函数的指针
说明signal返回的是一个函数指针,然后在看signal(这里),是 int signo, void(*func)(int) 眼熟么,第一个参数是int, 第二个参数是函数指针。
当然这是自我折腾的函数声明,其实人民也会这样定义它。
typedef void Signalfunc(int);
Signalfunc * signal(int, Signalfunc *);
好了,这回还看不懂。。。就去多读书孩子。。
说了那么多,signal可以做几件事情,我们关心的有:
1. 屏蔽对一些信号的响应,传入 Signalfunc = SIG_IGN
一般来说,SIG_IGN 的定义是: #define SIG_IGN (void (*)()) 1,我暂时没有找到他在头文件里的定义,有兴趣可以找找。
2. 修改对一些信号的响应,自己定义一个Signalfunc函数,传到signal接口里就行了。
要注意的事情是,参数 SIGKILL 和 SIGSTOP 不能覆盖或者屏蔽。
最后贴一段代码,测试signal函数
#include
#include
static void sig_usr(int);
int main()
{
if (signal(SIGUSR1, sig_usr) == SIG_ERR)
printf("can't catch SIGUSR1\n");
if (signal(SIGUSR2, sig_usr) == SIG_ERR)
printf("can't catch SIGUSR2\n");
for (;;)
sleep(1);
}
static void sig_usr(int signo)
{
if (signo == SIGUSR1)
printf("recevied SIGUSR1\n");
else
if (signo = SIGUSR2)
printf("recevied SIGUSR2\n");
else
printf("recevied signal %d\n", signo);
}
下班了,准备出趟门,对了SIGUSR1和SIGUSR2是系统默认给用户自定义的。
测试这个函数的方法是:
mattchen@ooxx:~/code/signal$ ./a.out &
[1] 15781
mattchen@ooxx:~/code/signal$ kill -USR1 15781
recevied SIGUSR1
mattchen@ooxx:~/code/signal$ kill -USR2 15781
recevied SIGUSR2
mattchen@ooxx:~/code/signal$ kill -9 15781