进程池在服务器应用中有很多很多=。=

下面是半同步半异步进程池的实现代码:

#ifndef _PROCESSPOOL_H
#define _PROCESSPOOL_H

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

class process
{
	public:
		process():m_pid(-1){}
	public:
		pid_t m_pid;
		int m_pipefd[2];
};

template
classe processpool
{
	private:
		//构造函数私有,类似于单例
		proceepool(int listenfd,int process_number = 8);
	public:
		static processpool* create(int listenfd,int process_number = 8)
		{
			if(!m_instance)
			{
				m_instance = new processpool(listenfd,process_number);
			}
			return m_instance;
		}
		~processpool()
		{
			delete [] m_sub_process;
		}
	private:
		void setup_sig_pipe();
		void run_parent();
		void run_child();
	
	private:
		//允许最大的子进村数量
		static const int MAX_PROCESS_NUMBER = 16;
		//子紧凑最多能处理的客户数量
		static const int USER_PER_PROCESS = 65536;
		//epoll最多处理的事件数
		static const int MAX_EVENT_NUMEBR = 1000;
		//进程池进程总数
		int m_process_number;
		//子进程在池中的序号,0开始
		int m_idx;
		//每个紧凑都有一个epool内核事件表,用m_epollfd标识
		int m_epollfd;
		//监听socket
		int m_listenfd;
		//子进程通过m_stop来决定是否停止运行
		int m_stop;
		//保存所有子进程的描述信息
		process* m_sub_process;
		//进程池实例
		static process* m_instance;
};

template 
processpool* processpool::m_instance = NULL;

static int sig_pipefd[2];

static 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;
}

static void addfd(int epollfd,int fd)
{
	epoll_fd event;
	event.data.fd = fd;
	event.events = EPOLLIN|EPOLLET;
	epoll_ctl(epollfd,EPOLL_CTL_ADD,fd,&event);
	setnonblocking(fd);
}

static void removefd(int epollfd,int fd)
{
	epoll_ctl(epollfd,EPOLL_CTL_DEL,fd,0);
	close(fd);
}

static void sig_handler(int sig)
{
	int save_errno = errno;
	int msg = sig;
	send(sig_pipefd[1],(char *)&msg,1,0);
	errno = save_errno;
}

static void addsig(int sig,void(handler)(int),bool restart = true)
{
	struct sigaction sa;
	memset(&sa,'\0',sizeof(sa));
	sa.sa_handler = handler;
	if(restart)
	{
		sa.sa_flags = SA_RESTAT;
	}
	sigfillset(&sa.sa_mask);
	assert(sigaction(sig,&sa,NULL)!= -1);
}

template
processpool::processpool(int listenfd,int process_number)
	:m_listenfd(listenfd),m_process_numebr(process_number),m_ide(-1),m_stop(false)
{
	assert((process_number>0)&&(process_number<=MAX_PROCESS_NUMBER));
	m_sub_process = new process[process_number];
	assert(m_sub_process);
	for(int i =0;i= 0);
		if(m_sub_procee[i].m_pid > 0)
		{
			close(m_sub_process[i].m_pipefd[1]);
			continue;
		}
		else
		{
			close(m_sub_process[i].m_pipefd[0]);
			m_idx = i;
			break;
		}
	}
	
}

template
void processpool::setup_sig_pipe()
{
	m_epollfd = epoll_create(5);
	assert(m_epollfd != -1);

	int ret = socketpair(PF_UNIX,SOCK_STREAM,0,sig_pipefd);
	assert(ret!= -1);

	setnonblocking(sig_pipefd[1]);
	addfd(m_epollfd,sig_pipefd[0]);

	addsig(SIGCHLD,sig_handler);
	addsig(SIGTERM,sig_handler);
	addsig(SIGINT,sig_handler);
	addsig(SIGPIPE,SIG_IGN);
}

template
void processpool::run_child()
{
	setup_sig_pipe();

	int pipefd = m_sub_process[m_idx].pipefd[1];

	addfd(m_epollfd,pipefd);

	epoll_event events[MAX_EVENT_NUMBER];
	T* users = new T[USER_PER_PROCESS];
	assert(users);
	int number = 0;
	int ret = -1;
	while(! m_stop)
	{
		number = epoll_wait(m_epollfd,events,MAX_EVENT_NUMBER,-1);
		if((number < 0) && (errno !=EINTR))
		{
			printf("epoll failure\n");
			break;
		}

		for(int i = 0;i0)
									{
										continue;
									}
									break;
								}
							case SIGTERM:
							case SIGINT:
								{
									m_stop = true;
									break;
								}
							default:
								{
									break;
								}
						}
					}
				}
			}
			else if(events[i].events&EPOLLIN)
			{
				users[sockfd].process();
			}
			else
			{
				continue;
			}
		}
	}
	delete [] users;
	users = NULL;
	close(pipefd);
	close(m_epollfd);
}

template
void processpool::run_parent()
{
	setup_sig_pipe();

	addfd(m_epollfd,m_listenfd);

	epoll_event events[MAX_EVENT_NUMBER];

	int sub_process_counter = 0;
	int new_conn = 1;
	int number = 0;
	int ret = -1;

	while(!m_stop)
	{
		number = epoll_wait(m_epollfd,events,MAX_EVENT_NUMBER,-1);
		if((number< 0) &&(errno!=EINTER))
		{
			printf("epoll failure\n");
			break;
		}
		for(int i = 0;i0)
									{
										for(int i = 0;i