Linux信号处理统一事件源
来源:互联网 发布:nginx重启 编辑:程序博客网 时间:2024/06/07 20:50
#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <assert.h>#include <stdio.h>#include <signal.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <fcntl.h>#include <stdlib.h>#include <sys/epoll.h>#include <pthread.h>#define MAX_EVENT_NUMBER 1024static int pipefd[2];int setnonblocking( int fd ){ int old_option = fcntl( fd, F_GETFL ); int new_option = old_option | O_NONBLOCK; fcntl( fd, F_SETFL, new_option ); return old_option;}void addfd( int epollfd, int fd ){ epoll_event event; event.data.fd = fd; event.events = EPOLLIN | EPOLLET; epoll_ctl( epollfd, EPOLL_CTL_ADD, fd, &event ); setnonblocking( fd );}//信号处理函数void sig_handler( int sig ){ int save_errno = errno; int msg = sig; send( pipefd[1], ( char* )&msg, 1, 0 ); errno = save_errno;}//设置信号的处理函数void addsig( int sig ){ struct sigaction sa; memset( &sa, '\0', sizeof( sa ) ); sa.sa_handler = sig_handler; sa.sa_flags |= SA_RESTART; sigfillset( &sa.sa_mask ); assert( sigaction( sig, &sa, NULL ) != -1 );}int main( int argc, char* argv[] ){ if( argc <= 2 ) { printf( "usage: %s ip_address port_number\n", basename( argv[0] ) ); return 1; } const char* ip = argv[1]; int port = atoi( argv[2] ); int ret = 0; struct sockaddr_in address; bzero( &address, sizeof( address ) ); address.sin_family = AF_INET; inet_pton( AF_INET, ip, &address.sin_addr ); address.sin_port = htons( port ); int listenfd = socket( PF_INET, SOCK_STREAM, 0 ); assert( listenfd >= 0 ); //int nReuseAddr = 1; //setsockopt( listenfd, SOL_SOCKET, SO_REUSEADDR, &nReuseAddr, sizeof( nReuseAddr ) ); ret = bind( listenfd, ( struct sockaddr* )&address, sizeof( address ) ); if( ret == -1 ) { printf( "errno is %d\n", errno ); return 1; } //assert( ret != -1 ); ret = listen( listenfd, 5 ); assert( ret != -1 ); epoll_event events[ MAX_EVENT_NUMBER ]; int epollfd = epoll_create( 5 ); assert( epollfd != -1 ); addfd( epollfd, listenfd ); //使用socketpair创建管道,注册pipefd[0]上的可读事件 ret = socketpair( PF_UNIX, SOCK_STREAM, 0, pipefd ); assert( ret != -1 ); setnonblocking( pipefd[1] ); addfd( epollfd, pipefd[0] ); //设置一些信号的处理函数 addsig( SIGHUP ); addsig( SIGCHLD ); addsig( SIGTERM ); addsig( SIGINT ); bool stop_server = false; while( !stop_server ) { int number = epoll_wait( epollfd, events, MAX_EVENT_NUMBER, -1 ); if ( ( number < 0 ) && ( errno != EINTR ) ) { printf( "epoll failure\n" ); break; } for ( int i = 0; i < number; i++ ) { int sockfd = events[i].data.fd; //如果就绪的文件描述符时listenfd,则处理新的连接 if( sockfd == listenfd ) { struct sockaddr_in client_address; socklen_t client_addrlength = sizeof( client_address ); int connfd = accept( listenfd, ( struct sockaddr* )&client_address, &client_addrlength ); addfd( epollfd, connfd ); } //如果就绪的文件描述符是pipefd[0],则处理信号 else if( ( sockfd == pipefd[0] ) && ( events[i].events & EPOLLIN ) ) { int sig; char signals[1024]; ret = recv( pipefd[0], signals, sizeof( signals ), 0 ); if( ret == -1 ) { continue; } else if( ret == 0 ) { continue; } else { //因为每个信号值占1字节,所以按字节来逐个接收信号。我们以 //SIGTERM为例,来说明如何安全地终止服务器主循环 for( int i = 0; i < ret; ++i ) { //printf( "I caugh the signal %d\n", signals[i] ); switch( signals[i] ) { case SIGCHLD: case SIGHUP: { continue; } case SIGTERM: case SIGINT: { stop_server = true; } } } } } else { } } } printf( "close fds\n" ); close( listenfd ); close( pipefd[1] ); close( pipefd[0] ); return 0;}
0 0
- Linux信号处理统一事件源
- Linux信号与统一事件源
- libevent源码学习-----统一事件源及信号绑定函数
- linux 信号&信号处理
- linux 信号&信号处理
- linux 信号&信号处理
- linux网络编程十八:统一事件源
- linux网络编程二十八:多线程编程之统一信号处理
- Linux信号与信号处理
- Linux信号和信号处理
- linux信号处理 信号 定时器
- Linux信号与信号处理
- Linux信号与信号处理
- 统一事件源
- 统一事件源简介
- 利用epoll统一调度信号、定时器和事件
- [linux] SIGPIPE信号处理
- Linux中的信号处理
- 心烦意乱的最后30天
- 网络编程概述
- Knockout应用开发指南 第七章:Mapping插件
- Lorem ipsum是什么(墙之后看的维基百科转过来的)
- jQuery判断某个地方是不是正在处于动画中is(":animated")
- Linux信号处理统一事件源
- 数组指针和指针数组
- mysql数据库备份
- 关于如何自己写一个数据库连接池(转)
- 无缝滚动
- 使用JS上传图片进行预览
- 高效运维的本质:可视化的服务交付和可视化的服务度量
- C语言字符串操作大全
- 来看看未来住宅如何加特技吧~!