信号可以在进程间进行传递,Linux的异步通知就是基于信号进行实现的。在Linux中可以使用的信号如下所示:
除了SIGSTOP和SIGKILL信号外,其余信号均能被进程忽略或捕获。
信号的接收:在用户进程中可以使用signal()函数设置相应的信号处理处理函数。类似于MCU中的中断,当满足触发中断条件的时候,就会去执行相对应的中断处理函数。
signal()函数原型如下:
void (*signal(int signum, void (*handler))(int)))(int);
第一个参数指定信号。 第二个参数指定信号对应的处理函数。
下面编写一个程序验证信号的接收:
1 #include2 #include 3 #include 4 5 void sigterm_handler(int signo) 6 { 7 printf("rnSig N.o is %drn", signo); 8 exit(0); 9 } 10 11 int main() 12 { 13 signal(SIGINT, sigterm_handler); 14 15 while(1); 16 return 0; 17 }
①signal函数的第一个参数是SIGINT,代表的是中端退出
②signal函数指定的第二个参数是信号处理函数sigterm_handler,他会打印接收到的信号值。
编译并运行结果如如所示:
在进程执行的时候,按下ctrl+C就会发送SIGINT信号,因此信号处理函数就会打印messege。
信号实现异步通知:1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 8 #define MAX_LEN 100 9 10 void input_handler(int num) 11 { 12 char data[MAX_LEN]; 13 int len; 14 15 16 len = read(STDERR_FILENO, &data, MAX_LEN); 17 data[len] = 0; //添加字符串结尾0 18 printf("input data :%srn",data); 19 } 20 21 22 int main() 23 { 24 int oflags; 25 26 27 signal(SIGIO, input_handler); 28 fcntl(STDIN_FILENO, F_SETOWN, getpid()); //设置本进程文STDIN_FILENO的所有者 29 oflags = fcntl(STDIN_FILENO, F_GETFL); 30 fcntl(STDIN_FILENO, F_SETFL, oflags | FASYNC); 31 32 while(1); 33 34 35 return 0; 36 }
本程序对标准输入的文件描述符STDIN_FILENO启动信号机制,每当用户输入时,进程将接收到SIGIO信号,信号处理函数将会被调用打印输入的messege。
验证:为了能在用户空间处理一个设备的信号,需要完成三个步骤:
① 通过F_SETOWN命令设置文件的拥有者为本进程,只有这样设备文件才知道信号发给谁
② 通过F_SETFL命令设置设备文件为FASYNC,异步通知模式。
③ 通过signal()函数连接信号和信号处理函数。



