信号处理机制在linux编程中非常重要,它类似于单片机中的中断系统;我们在编写中断函数时,需要设置中断函数的地址,设置其相应的寄存器,以便于发生中断事件时可以正确的跳到中断函数去执行;
linux中信号和这个类似,一般的编程模型是定义中断函数,然后把中断函数注册,使得进程收到特定的信号时,可以跳到信号处理函数去执行;
1.kill函数与raise函数
kill函数用来将信号发送给进程或进程组;
——int kill(pid_t pid, int signo);
raise函数则允许进程向自身发送信号;
——int raise(int signo);
调用raise(signo);等价于kill(getpid(), signo);
不仅仅是kill函数 kill命令也可以用来发送信号:
如:
kill -l ——列出所有信号
kill -s 10 pid —— 10代表SIGUSR1 pid代表向哪个进程发送USR1信号
也可以这样写:kill -USR1 pid
回到kill函数;
注意:kill函数的第一个参数:
下面是一个使用kill函数的例子:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
pid_t pid;
void fun(int a)
{
if(a == SIGABRT)
printf("Have fun!\n");
if(a == SIGUSR1)
{
printf("Fuck!\n");
}
}
void send()
{
kill(pid, SIGUSR1);// Only send msg to progress or progress group!
}
int main()
{
int cnt = 0;
signal(SIGABRT, fun);
signal(SIGUSR1, fun);
pid = fork();
if(pid == 0)
{
while(1)
{
printf("Child!\n");
sleep(1);
}
}
while(1)
{
printf("Father!\n");
cnt++;
if(cnt == 5)
send();
sleep(1);
}
}
2. alarm函数和pause函数
alarm函数用来设定计时器,设定的某个时间超时时,会产生一个SIGALRM信号,如果不捕捉改信号,默认会终止调用该alarm函数的进程。
—— unsigned int alarm(unsigned int seconds);
pause函数使得调用进程挂起直到捕捉到一个信号。
—— int pause(void);
实例:
#include <signal.h>
#include <stdio.h>
void fun(int id)
{
if(id == SIGUSR1)
{
printf("SIGUSR1\n");
}
if(id == SIGALRM)
{
printf("SIGALRM!\n");
}
}
int main()
{
signal(SIGUSR1, fun);
signal(SIGALRM, fun);
alarm(5); // if not catch, progress return;
for(;;)
pause();
return 0;
}
3.信号集
一个可以包含多个信号的信号集,这个数据类型是sigset_t,同时,也有相应的信号集函数;
还有下列一些函数: