概念:
信号时一种异步事件:信号处理函数和程序的主循环式两条不同的执行路线,信号处理函数需要尽可能快地执行完毕,以确保该信号不被屏蔽.(为了避免一些竞态条件,信号在处理期间,系统不会再次出发它)太久.这里就采用一种常用的解决方案是:把信号的主要处理函数逻辑放到程序的主循环中,当信号处理函数被触发时,它只是简单地通知主循环程序接受到信号,并把信号值传递给主函数.主循环在根据接受到的信号值执行目标信号对应的处理逻辑代码.通常采用管道的方式来将"信号"传递给主循环.主程序采用I/O复用模型来将信号事件和其他事件统一处理.即统一事件源.
代码实例:
1 #include <sys/types.h> 2 #include <sys/socket.h> 3 #include <netinet/in.h> 4 #include <arpa/inet.h> 5 #include <stdio.h> 6 #include <string.h> 7 #include <stdlib.h> 8 #include <fcntl.h> 9 #include <sys/epoll.h> 10 #include <pthread.h> 11 #include <errno.h> 12 #include <signal.h> 13 14 #define MAX_EVENT_NUMBER 1024 15 static int pipefd[2]; 16 17 int setnonblocking(int fd){ 18 int old_option=fcntl(fd,F_GETFL); 19 int new_option=old_option | O_NONBLOCK; 20 21 fcntl(fd,F_SETFL,new_option); 22 return old_option; 23 } 24 25 void addfd(int epollfd,int fd){ 26 struct epoll_event event; 27 event.data.fd=fd; 28 event.events =EPOLLIN | EPOLLET; 29 epoll_ctl(epollfd,EPOLL_CTL_ADD,fd,&event); 30 setnonblocking(fd); 31 } 32 33 void sig_handler(int sig){ 34 int save_errno=errno; 35 int msg=sig; 36 send(pipefd[1],(char*)&msg,1,0); 37 errno=save_errno; 38 } 39 40 41 void addsig(int sig){ 42 struct sigaction sa; 43 memset(&sa,'