The process pool is a lot more in server applications. =
The following is the implementation code for the semi-synchronous semi-asynchronous process pool:
#ifndef _PROCESSPOOL_H#define _PROCESSPOOL_H#include<sys/types.h> #include <sys/socket.h># include<netinet/in.h> #include <arpa/inet.h> #include <assert.h> #include <stdio.h> #include <unistd.h> #include <errno,h> #include <string.h> #include <fcntl.h> #include <stdlib.h> #include <signal.h> #include <sys/wait.h> #include <sys/stat.h>class process{public:process ( ): M_pid ( -1) {}public:pid_t m_pid;int m_pipefd[2];}; The template<typename t>classe processpool{private://constructor is private, similar to the singleton Proceepool (int listenfd,int process_number = 8);p ublic:static processpool<t>* create (int listenfd,int &NBSP;PROCESS_NUMBER&NBSP;=&NBSP;8) {if (!m_instance) {m_instance = new processpool<t> ( Listenfd,process_number);} Return m_instance;} ~processpool () {delete [] m_sub_process;} Private:void setup_sig_pipe (); Void run_parent (); void run_child();p rivate://Maximum number of sub-villages allowed static const int max_process_number = 16;//sub-compact maximum number of customers to handle static const int user_per_process = 65536;//epoll the maximum number of events processed static const int max_event_numebr = 1000;//number of Process pool processes int m_process_number;//the number of child processes in the pool, 0 starts int m_idx;// Each compact has a Epool kernel event table that uses M_EPOLLFD to identify the int m_epollfd;//listener socketint m_listenfd;//child process to decide whether to stop running int by m_stop m_stop;//Save descriptive information for all child processes process* m_sub_process;//Process pool instance static process<t>* m_instance;}; Template <class t>processpool<t>* processpool<t>::m_instance = null ; static int sig_pipefd[2];static int setnonblocking (INT&NBSP;FD) {int old_option = fcntl (FD,F_GETFL); Int new_option = old_option | o_nonblock;fcntl (Fd,F_SETFL, new_option); return old_option;} STATIT&NBSP;VOID&NBSP;ADDFD (INT&NBSP;EPOLLFD,INT&NBSP;FD) {Epoll_fd event;event.data.fd = fd;event.events = epollin| Epollet;epoll_ctl (epollfd,epoll_ctl_add,fd,&event); setnonblocking (FD);} STACIT&NBSP;VOID&NBSP;REMOVEFD (INT&NBSP;EPOLLFD,INT&NBSP;FD) {epoll_ctl (epollfd,epoll_ctl_del,fd,0); close (FD);} Stacit 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, ' sa.sa_flags ', sizeof (SA)); sa.sa_handler = handler;if (restart) { = sa_restat;} Sigfillset (&sa.sa_mask); Assert (Sigaction (sig,&sa,null)!= -1);} Template<class t>processpool<t>::p Rocesspool (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<process_ Number;++i) {Int ret = socketpair (PF_UINX,SOCK_STREAM,0,M_SUB_PROCESS[I].M_PIPEFD); ASSERT (ret == 0); M_sub_process[i].m_pid = fork (); assert (m_sub_procee[i].m_pid >= 0); 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<class t>void processpool<t>::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<class t>void processpool<t>::run_child () {setup_sig_pipe (); int pipefd =&NBSP;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); ((number < 0) && (ERRNO&NBSP;!=EINTR)) {printf ("epoll failure\n"); break;} for (int i = 0;i<number;++i) {int sockfd = events[i].data.fd;if (sockfd == &NBSP;PIPEFD) && (Events[i].events& epollin)) {int client = 0;ret = Recv (SOCKFD, (char*) &clinet,sizeof (client), 0); if ((ret <0) && (errno!=eagain)) | | ret == 0) {continue;} Else{struct sockaddr_in client_address;socklen_t client_addrlength = sizeof (Client_ ADDRSS); Int connfd = accept (M_LISTENFD, (struct sockaddr*) &client_address,&client_ Addrlength); if (connfd < 0) {printf ("errno is:%d\b", errno); continue;} ADDFD (M_EPOLLFD,CONNFD); Users[connfd].init (m_epollfd,connfd,client_address);}} Else if ((sockfd == sig_pipefd[0]) && (Events[i].events&epollin)) {Int sig;char &NBSP;SIGNALS[1024];RET&NBSP;=&NBSP;RECV (sig_pipefd[0],signals,sizeof (signals), 0); if (ret<= 0) {continue ;} Else{for (int i = 0;i< ret;++i) {switch (Signals[i]) {Case sigchld:{pid_t pid;int stat;while (Pid = waitpid ( -1,&stat,wnohang) >0) {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<class t>void processpool<t>::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"); for (int i = 0;i<number;++i) {int sockfd = events[i].data.fd;if (sockfd == &NBSP;M_LISTENFD) {int i = sub_process_counter;do{if (m_sub_process[i].m_pid != -1) { break;} i = (i+1)%m_process_number;} while (i!= sub_process_counter); if (m_sub_number[i].m_pid == -1) {m_stop = true;break;} sub_process_counter = (i+1)%m_process_number;send (M_sub_process[i].m_pipefd[0], (char*) &new_conn, sizeof (New_conn), 0);p rintf ("send request to child %d\n", I);} Else if ((sockfd == sig_pipefd[0]) && (Events[i].events &epollin)) { Int sig;char signals[1024];ret&NBSP;=&NBSP;RECV (sig_pipefd[0],signals,sizeof (signals), 0); if (ret<= 0) {continue;} Else{for (int i = 0;i<ret;++i) {switch (Signal[i]) {case sigchld:{pid_t pid;int Stat;while ((Pid = waitpid ( -1,&stat,wnohang)) >0) {for (Int i = 0;i<m_process_ Number;++i) {if (m_sub_process[i].m_pid== pid) {printf ("child %d join\n", I); Close (M_sub_process[i] . m_pipfd[0]); m_sub_process[i].m_pid = -1;}}} M_stop = true;for (int i = 0;i<m_process_number;++i) {if (m_sub_process[i].m_pid!= -1) {m_stop = false;}} break;} case sigterm:case sigint:{printf ("kill all the child now\n"); for (int i = 0;i<m_process_number;++i) {int pid = m_sub_process[i].m_pid;if (pid != -1) {Kill (Pid,sigterm);}} break;} Default:{break;}}}} else{continue;}}} Close (M_EPOLLFD);} #endif
This article from "Left Egg June" blog, reproduced please contact the author!
Linux: Process Pool Implementation