设为首页 加入收藏

TOP

c半同步半异步进程池模型之cgi服务器(一)
2016-09-19 18:03:17 】 浏览:1080
Tags:同步 异步 进程 模型 cgi 服务器

对半同步半异步进程池模型垂涎已久,这次中秋放假撸了下代码,代码写了几个模块,分别是:

util:封装了套接字创建、unix族socket管道创建、中断信号、简单屏幕输出(可自行替换为日志文件输出)

epoll_wrapper:封装了epoll相关操作包括创建epfd、添加epoll监听事件、删除epoll监听事件

myhshappool(我的半同步半异步进程池 - -!…):封装了进程池初始化、启动进程池进行事件监听

client_handle:进程池监听到客户事件、即调用client_handle封装的处理事件,这里封装的是执行cgi文件向客户端浏览器返回服务器时间(最近在看unix网络编程,里面都是时间获取的服务器,借鉴下拿来搞事,当然,嵌入式里拿来控制个灯泡开关想来特别带劲,用android做个网页app,板子接wifi模块接智能灯,cgi负责开关灯泡 。。)

cgisrv:入口,初始化进程池,启动进程池

代码快1k行,不知道一个博客文章能不能写下,不太会用github,况且这种玩具demo代码就不往github放了。代码中凑合写了注释(有时候不想切换中英文因此用了蹩脚的英文注释),限(wo)于(tai)篇(lan)幅(le)没有写文件头注释和函数头注释。

util.h:

#ifndef _UTIL_H
#define _UTIL_H

#include 
   
     #include 
    
      #include 
     
       #include 
      
        #include 
       
         #include 
        
          #include 
         
           #include 
          
            #include 
           
             #include 
            
              //这里不用 #转字符串了,不方便管理等级 #ifdef LEVELNUMPRINT #define LEVEL0 "LEVEL0" #define LEVEL1 "LEVEL1" #define LEVEL2 "LEVEL2" #define LEVEL3 "LEVEL3" #define LEVEL4 "LEVEL4" #define LEVEL4 "LEVEL5" #else #define LEVEL0 "DEBUG" #define LEVEL1 "INFO" #define LEVEL2 "NOTICE" #define LEVEL3 "WARN" #define LEVEL4 "ERROR" #define LEVEL5 "FATAL" #endif #define PRINTINFO( LEVEL, format, args... ) \ do { \ printf("[%s]:(pid:%d)/(file:%s)/(func:%s)/(line:%d)", \ LEVEL, getpid(), __FILE__, __func__, __LINE__); \ /*printf("\t" #LEVEL ":");*/ \ printf("--|--"); \ printf( format, ##args ); \ printf("\n"); \ } while( 0 ) #define PRINTINFO_ERR( LEVEL, format, args... ) \ do { \ printf("[%s]:(pid:%d)/(file:%s)/(func:%s)/(line:%d)", \ LEVEL, getpid(), __FILE__, __func__, __LINE__); \ /*printf("\t" #LEVEL ":");*/ \ printf("--|--"); \ printf( format, ##args ); \ printf("(errmsg:%s)", strerror(errno)); \ printf("\n"); \ } while( 0 ) void Add_sig( int sig, void (*handler)(int), int restart_syscall ); void Socketpair( int *pairpipefd ); int Socket_create( char *ipaddr, int port ); void Setnonblocking( int fd ); #endif 
            
           
          
         
        
       
      
     
    
   

util.c:

#include "util.h" static int add_sig( int sig, void (*handler)(int), int restart_syscall ) { struct sigaction act; bzero( &act, sizeof(act) ); act.sa_handler = handler; act.sa_flags = 0; //早期unix系统对于进程在执行一个低速系统调用(如ioctl、 //read、write、wait)而阻塞期间捕捉到一个信号,则系统 //调用被中断不再执行,该系统调用返回错误,设置errno为 //EINTR,随后的bsd系统引入了自动重启,即再次进行此系统 //调用。unix衍生系统默认的方式可能为可选、总是等,类 //unix系统的linux系统可能默认为不重启,因此添加重启标识 if ( restart_syscall ) { act.sa_flags |= SA_RESTART; } //宏定义: //#define sigfillset(*p) (*p) = ~(0,0) sigfillset( &act.sa_mask ); if ( -1 == sigaction(sig, &act, NULL) ) { PRINTINFO_ERR( LEVEL4, "sigaction error" ); return -1; } return 0; } void Add_sig( int sig, void (*handler)(int), int restart_syscall ) { if ( add_sig(sig, handler, restart_syscall) < 0 ) { PRINTINFO( LEVEL5, "add_sig error" ); exit( 0 ); } } void Socketpair( int *pairpipefd ) { int ret; ret = socketpair( PF_UNIX, SOCK_STREAM, 0, pairpipefd ); if ( ret < 0 ) { PRINTINFO_ERR( LEVEL5, "socketpair error!!" ); exit( 0 ); } } static int socket_create( char *ipaddr, int port, int backlog ) { int sockfd; int ret; sockfd = socket( AF_INET, SOCK_STREAM, 0 ); if ( sockfd < 0 ) { PRINTINFO_ERR( LEVEL4, "socket error!!!" ); return -1; } struct sockaddr_in addr; bzero( &addr, sizeof(addr) ) ; addr.sin_family = AF_INET; addr.sin_port = htons( port ); inet_pton( AF_INET, ipaddr, &addr.sin_addr ); int reuseaddr = 1; setsockopt( sockfd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(int) ); ret = bind( sockfd, (struct sockaddr *)&addr, (socklen_t)sizeof(addr) ) ; if ( ret < 0 ) { PRINTINFO_ERR( LEVEL4, "bind error!!!" ); return -1; } ret = listen( sockfd, backlog ); if ( ret < 0 ) { PRINTINFO_ERR( LEVEL4, "listen error!!!" ); return -1; } return sockfd; } int Socket_create( char *ipaddr, int port ) { int ret; ret = socket_create( ipaddr, port, 5 ); if ( ret < 0 ) { PRINTINFO( LEVEL5, "socket_creaet error!!!" ); exit( 0 ); } return ret; } static int setnonblocking( int fd ) { int old_opt = fcntl( fd, F_GETFL ); int new_opt = old_opt | O_NONBLOCK; fcntl( fd, F_SETFL, new_opt ); return old_opt; } void Setnonblocking( int fd ) { setnonblocking( fd ); } int Send ( int socket_fd, const unsigned char * send_buf, int buf_size, int flag ) { int snd_bytes = 0; int snd_total_bytes = 0; int snd_count = 3; while ( snd_count -- ) { snd_bytes = send( socket_fd, send_buf, buf_size, flag ); if ( snd_bytes <= 0 ) { if ( EAGAIN == errno || EINTR == errno || EWOULDBLOCK == errno ) { //暂时发送失败,需要重复发送 usleep( 50 ); continue; }else { //连接不正常,返回-1交由上层清理此套接字 PRINTINFO_ERR( LEVEL4, "send return error!!!" ); return -1; } } snd_total_bytes += snd_bytes; if ( snd_total_bytes >= buf_size ) { break; } } if ( !snd_count ) { PRINTINFO( LEVEL4, "send timeout!!!" ); return -1; } return snd_total_bytes; } #if 0 int main() { PRINTINFO( LEVEL0, "likun:%d", 123 ); PRINTINFO( LEVEL1, "likun:" ); //PRINTINFO( likun, "likun:" ); return 0; } #endif 

epoll_wrapper.h:

#ifndef _EPOLL_WRAPPER_H #define _EPOLL_WRAPPER_H #include 
     
       #include 
      
        int Epoll_create( int size ); int Epoll_wait( int epfd, struct epoll_event *events, int maxevents, int timeout ); void Epoll_add_fd( int epfd, int fd ); void Epoll_del_fd( int epfd, int fd ); #endif 
      
     

epoll_wrapper.c:

#include "epoll_wrapper.h" #include "util.h" static int epoll_create0( int size ) { int ret; ret = epoll_create( size ); if ( ret <= 0 ) { PRINTINFO_ERR( LEVEL3, "epoll_create error!!!" ); return -1; } return ret; } int Epoll_create( int size ) { int ret; if ( (ret = epoll_create0(size)) < 0 ) { PRINTINFO( LEVEL5, "epoll_create0 error!!!" ); exit( 0 ); } return ret; } int Epoll_wait( int epfd, struct epoll_event *events, int maxevents, int timeout ) { return epoll_wait( epfd, events, maxevents, timeout ); } static int epoll_add_fd( int epfd, int fd ) { struct epoll_event event; event.data.fd = fd; event.events = EPOLLIN | EPOLLET; epoll_ctl( epfd, EPOLL_CTL_ADD, fd, &event ); Setnonblocking( fd ); return 0; } void Epoll_add_fd( int epfd, int fd ) { epoll_add_fd( epfd, fd ); } void Epoll_del_fd( int epfd, int fd ) { epoll_ctl( epfd, EPOLL_CTL_DEL, fd, NULL ); } #if 0 int main() {} #endif 

myhshappool.h:

#ifndef _MY_HS_HA_P_POOL_H #define _MY_HS_HA_P_POOL_H #include 
       
         #inc
首页 上一页 1 2 3 4 5 下一页 尾页 1/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C语言的符号表和类型系统1 下一篇如何动态调用 C 函数

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目