Linux: Process Pool Implementation

Source: Internet
Author: User

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.