1. 统一事件源:
1 #include <sys/types.h> 2 #include <sys/socket.h> 3 #include <netinet/in.h> 4 #include <arpa/inet.h> 5 #include <assert.h> 6 #include <stdio.h> 7 #include <signal.h> 8 #include <unistd.h> 9 #include <errno.h> 10 #include <string.h> 11 #include <fcntl.h> 12 #include <stdlib.h> 13 #include <sys/epoll.h> 14 #include <pthread.h> 15 16 #define MAX_EVENT_NUMBER 1024 17 static int pipefd[2]; 18 19 int setnonblocking( int fd ) 20 { 21 int old_option = fcntl( fd, F_GETFL ); 22 int new_option = old_option | O_NONBLOCK; 23 fcntl( fd, F_SETFL, new_option ); 24 return old_option; 25 } 26 27 void addfd( int epollfd, int fd ) 28 { 29 epoll_event event; 30 event.data.fd = fd; 31 event.events = EPOLLIN | EPOLLET; 32 epoll_ctl( epollfd, EPOLL_CTL_ADD, fd, &event ); 33 setnonblocking( fd ); 34 } 35 36 void sig_handler( int sig ) 37 { 38 int save_errno = errno; 39 int msg = sig; 40 send( pipefd[1], ( char* )&msg, 1, 0 ); 41 errno = save_errno; 42 } 43 44 void addsig( int sig ) 45 { 46 struct sigaction sa; 47 memset( &sa, ‘\0‘, sizeof( sa ) ); 48 sa.sa_handler = sig_handler; 49 sa.sa_flags |= SA_RESTART; 50 sigfillset( &sa.sa_mask ); 51 assert( sigaction( sig, &sa, NULL ) != -1 ); 52 } 53 54 int main( int argc, char* argv[] ) 55 { 56 if( argc <= 2 ) 57 { 58 printf( "usage: %s ip_address port_number\n", basename( argv[0] ) ); 59 return 1; 60 } 61 const char* ip = argv[1]; 62 int port = atoi( argv[2] ); 63 64 int ret = 0; 65 struct sockaddr_in address; 66 bzero( &address, sizeof( address ) ); 67 address.sin_family = AF_INET; 68 inet_pton( AF_INET, ip, &address.sin_addr ); 69 address.sin_port = htons( port ); 70 71 int listenfd = socket( PF_INET, SOCK_STREAM, 0 ); 72 assert( listenfd >= 0 ); 73 74 //int nReuseAddr = 1; 75 //setsockopt( listenfd, SOL_SOCKET, SO_REUSEADDR, &nReuseAddr, sizeof( nReuseAddr ) ); 76 ret = bind( listenfd, ( struct sockaddr* )&address, sizeof( address ) ); 77 if( ret == -1 ) 78 { 79 printf( "errno is %d\n", errno ); 80 return 1; 81 } 82 //assert( ret != -1 ); 83 84 ret = listen( listenfd, 5 ); 85 assert( ret != -1 ); 86 87 epoll_event events[ MAX_EVENT_NUMBER ]; 88 int epollfd = epoll_create( 5 ); 89 assert( epollfd != -1 ); 90 addfd( epollfd, listenfd ); 91 92 ret = socketpair( PF_UNIX, SOCK_STREAM, 0, pipefd ); 93 assert( ret != -1 ); 94 setnonblocking( pipefd[1] ); 95 addfd( epollfd, pipefd[0] ); 96 97 // add all the interesting signals here 98 addsig( SIGHUP ); 99 addsig( SIGCHLD ); 100 addsig( SIGTERM ); 101 addsig( SIGINT ); 102 printf("SIGHUP:%d, SIGCHLD:%d, SIGTERM:%d, SIGINT:%d\n", SIGHUP, SIGCHLD, SIGTERM, SIGINT); 103 bool stop_server = false; 104 105 while( !stop_server ) 106 { 107 int number = epoll_wait( epollfd, events, MAX_EVENT_NUMBER, -1 ); 108 if ( ( number < 0 ) && ( errno != EINTR ) ) 109 { 110 printf( "epoll failure\n" ); 111 break; 112 } 113 114 for ( int i = 0; i < number; i++ ) 115 { 116 int sockfd = events[i].data.fd; 117 if( sockfd == listenfd ) 118 { 119 struct sockaddr_in client_address; 120 socklen_t client_addrlength = sizeof( client_address ); 121 int connfd = accept( listenfd, ( struct sockaddr* )&client_address, &client_addrlength ); 122 addfd( epollfd, connfd ); 123 } 124 else if( ( sockfd == pipefd[0] ) && ( events[i].events & EPOLLIN ) ) 125 { 126 int sig; 127 char signals[1024]; 128 ret = recv( pipefd[0], signals, sizeof( signals ), 0 ); 129 if( ret == -1 ) 130 { 131 continue; 132 } 133 else if( ret == 0 ) 134 { 135 continue; 136 } 137 else 138 { 139 for( int i = 0; i < ret; ++i ) 140 { 141 printf( "I caugh the signal %d\n", signals[i] ); 142 switch( signals[i] ) 143 { 144 case SIGCHLD: 145 case SIGHUP: 146 { 147 continue; 148 } 149 case SIGTERM: // kill pid 150 case SIGINT: // 键盘Ctrl+C 151 { 152 stop_server = true; 153 } 154 } 155 } 156 } 157 } 158 else 159 { 160 } 161 } 162 } 163 164 printf( "close fds\n" ); 165 close( listenfd ); 166 close( pipefd[1] ); 167 close( pipefd[0] ); 168 return 0; 169 }
运行:
[zf@localhost 10]$ ./a.out 127.0.0.1 1236 SIGHUP:1, SIGCHLD:17, SIGTERM:15, SIGINT:2 ^CI caugh the signal 2 (执行Ctrl + C) close fds [zf@localhost 10]$ ./a.out 127.0.0.1 1237 SIGHUP:1, SIGCHLD:17, SIGTERM:15, SIGINT:2 I caugh the signal 15 (被kill杀死) close fds
2.信号函数
#include <signal.h> int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
struct sigaction { void (*sa_handler)(int); // 信号处理函数 void (*sa_sigaction)(int, siginfo_t *, void *); sigset_t sa_mask; // 信号掩码 int sa_flags; // 设置信号行为 void (*sa_restorer)(void); };
signum:信号类型
act: 新的信号处理
oact:返回之前的信号处理