信号是软件中断。信号名都被定义为正整数常量,不存杂编号为0的信号。
对于信号的处理,有如下的几种方式:
(1)忽略此信号:有两种信号绝对不可以忽略,1.SIGKILL和2.SIGSTOP,不能忽略是因为提供了使得进程终止或停止的可靠方法。
(2)捕捉信号:要通知内核在某种信号发生的时候,调用一个用户函数。
(3)执行系统默认动作
//成功则返回以前的信号处理配置,出错则返回SIG_ERR
//函数的返回值为一个函数指针,该函数中传递一个int类型的参数
void (*signal(int signo,void (*func)(int)))(int)
signo:
信号名
func:
SIG_IGN 忽略此信号
SIG_DFL 系统默认动作
函数指针 所调用的函数,注意signo会作为唯一的int参数传递给这个指针
//注意,内核中定义这些宏的时候是直接定义为函数指针的
#define SIG_ERR (void (*) ()) -1 //将-1强制转化为函数指针
#define SIG_DFL (void (*) ()) 0
#define SIG_IGN (void (*) ()) 1
一个示范的例子
void sig_handler(int sig)
{
switch(sig):
{
case(SIGUSR1):
cout<<"SIGUSR1 received"<<endl;
case(SIGUSR2):
cout<<"SIGUSR2 received"<<endl;
}
}
int main()
{
if(SIG_ERR==signal(SIGUSR1,sig_handler))
return -1;
if(SIG_ERR==signal(SIGUSR2,sig_handler))
return -1;
}
exec函数将原先设置为要捕捉的信号都更改为默认动作,其他信号的状态则保持不变,这是因为人家都执行新的程序了就不要折磨人家了
函数kill将信号发送给进程或者进程组,raise函数允许进程向自身发送信号
//成功则返回0,否则返回-1
int kill(pid_t pid,int signo)
pid:
>0 将信号发送给pid进程
==0 发送给发送进程同一个进程组中的所有进程
<0 发送给进程组为pid的绝对值的进程组
==-1 发送给所有有权限发送的进程
signo:
信号
int raise(int signo)
相当于 kill(getpid(),signo)
//pause函数只有执行了一个信号处理函数并从中返回才会返回
int pause(void)
挂起直到捕捉到一个信号