信号-(1)

1、信号是什么?


信号本质上就是一个整数,系统用信号实现中断。信号都有一个宏名称,都以SIG开头,比如:SIGINT就是信号2.

POSIX规范中没有定义整数的规范,而是用了宏名称做规范。因此使用宏名称代表信号有更好的通用性。

查看信号的命令: kill –l


1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 总线 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX


3 信号的特点:


信号分为可靠和不可靠信号,对于Linux系统来说,1-31的是不可靠信号,主要特点是不支持排队,因此可能发生信号的丢失,非实时信号。34-64的是可靠信号,主要特点是支持排队,不会造成信号的丢失,是实时信号。
程序中,无法确定信号什么时候会来,信号来不来也无法确定。(异步方式)


4 信号的来源


信号函数和硬件故障。


5 信号处理方式

默认处理,采用系统默认处理方式。80%以上都是中止进程。
忽略处理,忽略信号的到来。
自定义处理函数,执行自己的代码。
注:信号9不能被忽略,也不能自定义,只能默认。当前用户只能给自己用户的进程发信号,但root能给所有用户的进程发信号。


6 修改信号处理方式,需要使用信号注册函数:


signal() 或 sigaction()
void (*fa) (int) signal(int signum,
void (*fa) (int))
参数:signum 就是信号(整数)


fa有三种可能:

SIG_IGN 忽略
SIG_DFL 默认
自定义的函数名(函数指针)


使用步骤:
1 先定义一个函数void fa(int signo)。
2 使用signal()完成注册。

例子
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>

void fa(int signo)
{//参数就是信号的值
  printf("捕获了信号%d ",signo);
}
int main()
{
  signal(SIGINT,fa);//注册了信号2的处理函数
  signal(SIGQUIT,SIG_IGN);//忽略了信号3
  signal(SIGKILL,SIG_IGN);//9信号无法忽略和自定义
  if(signal(SIGFPE,fa)==SIG_ERR)
  {//判断是否注册成功
    perror("signal"),exit(-1);
  } 
  while(1);
}

aiyq195@aiyq195-virtual-machine:~/桌面/uc/day07$ ./signal
^C捕获了信号2
^C捕获了信号2
^C捕获了信号2
^C捕获了信号2
^C捕获了信号2
^C捕获了信号2
^C捕获了信号2

用了ctrl+z
或者 使用kill -9 命令杀死进程

aiyq195@aiyq195-virtual-machine:~$ ps -aux|grep signal
aiyq195 6732 97.0 0.0 2004 280 pts/0 R+ 22:06 0:12 ./signal
aiyq195 6735 0.0 0.0 6084 840 pts/1 S+ 22:06 0:00 grep --color=auto signal


aiyq195@aiyq195-virtual-machine:~$ kill -9 6732

aiyq195@aiyq195-virtual-machine:~/桌面/uc/day07$ ./signal

[1]+ 已杀死 ./signal
已杀死

信号的发送方式:


1 键盘发送 (部分信号)
Ctrl+C -> 发送信号2
Ctrl+ -> 发送信号3
Ctrl+Z -> 发送信号20
2 出错 (部分信号)
段错误 -> 信号11 SIGSEGV
总线错误 -> 信号7 SIGBUS
整数除以0 -> 信号8 SIGFPE
3 kill 命令 发送,格式:(所有信号)
kill -信号 进程PID
4 函数发送信号(部分/所有信号)
kill() - 发送任意信号给任意进程
raise() - 发送任意信号给本进程
alarm() - 闹钟函数,通过产生闹钟信号工作
sigqueue() - 发送信号的同时还能附加数据

例子1:关于raise()函数


#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void fa(int signo){
printf("get the signal %d ",signo);
}
int main(){
signal(SIGINT,fa);
raise(SIGINT);
int res = sleep(10);
printf("res=%d ",res);
raise(SIGQUIT);//信号3,也就是10秒后,将会退出
while(1);
}

结果如下:
[root@aiyq195 day08]# vi raise.c
[root@aiyq195 day08]# gcc raise.c -o raise
[root@aiyq195 day08]# ./raise
get the signal 2
res=0
Quit (core dumped)

其中sleep() 函数,是可能不会按照设定的时间睡眠,
sleep()函数被没有忽略的信号打断,此时返回睡眠的剩余秒数。

usleep()函数能设置更小的休眠时间,到微秒。usleep()和信号无关。
微妙相当于秒的10的-6次方;

例子: kill() 函数

kill() 是发送信号的主体函数,格式:
int kill(pid_t pid,int signo);
参数pid取值的效果和waitpid()效果一样,常见的有:
>0 对应PID的进程
-1 所有进程(要求有权限)
0 所在组所有的进程发送信号;

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
void fa(int signo){
printf("course is %d capture the signal is %d ",getpid(),signo);
}
int main(){
pid_t pid = fork();
if(pid == 0){
signal(SIGINT,fa);
printf("child:pid=%d ",getpid());
sleep(10);
exit(0);
}
sleep(1);
kill(pid,SIGINT);//kill函数pid在前
}

[root@aiyq195 day08]# vi kill1.c
[root@aiyq195 day08]# gcc kill1.c -o kill1
[root@aiyq195 day08]# ./kill1
child:pid=2638
course is 2638 capture the signal is 2
结果表明:
子进程捕获了信号 SIGINT 2;


例子3:alarm() 闹钟函数


- 闹钟函数,
一段时间之后产生闹钟信号
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
Int main()
{
Alarm(1);
While(1);
}

[root@aiyq195 day08]# gcc alarm1.c -o alarm1
[root@aiyq195 day08]# ./alarm1
Alarm clock
结果说明了,alarm 会在自己规定的时间内,去响应闹钟,然后关闭进程;

原文地址:https://www.cnblogs.com/aiyq195/p/6428343.html