Process Pool Model

Source: Internet
Author: User
Tags epoll sprintf server port htons


The process pool model needs to be synchronized through the system V IPC mechanism or pipelines, signals, file locks, and so on. The following is a generic model of the process pool.

650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M02/72/54/wKioL1XhTHnwwGnnAAEcmdVtU6Y290.jpg "title=" Image 4.png "alt=" Wkiol1xhthnwwgnnaaecmdvtu6y290.jpg "/>


Linux Surprise cluster phenomenon:

Surprise group: When multiple processes/threads wait for the same resource, all processes/threads compete for resources whenever resources are available.

The cluster phenomenon when accept, select, Epoll implements the process pool model:

1). The cluster problem of the Linux multi-process accept system call (note that there is no event mechanism such as SELECT, Epoll, etc.) that existed before the Linux 2.6 release and was resolved in later versions.

2). Using event mechanisms such as Select Epoll, the cluster problem persists in earlier versions of Linux (epoll_create before fork). The reason is similar to the previous simple use of accept to cause surprise groups. The Epoll problem, which was also solved in some later version of the group.

3). Epoll_create after fork call, can not avoid surprise group problem, nginx use mutual exclusion lock, solve Epoll surprise group problem.

Process call accept in process pool if blocking is in the same listen queue, it is possible to generate a panic cluster (depending on the Linux version): When a connect arrives, all accept will wake up, but only one accept will return the correct result, and the others will return the error code.

accept multi-process implementations : Let a process bind a network address (possibly Af_inet,af_unix or whatever you want), and then fork the process yourself:


int s = socket (...)

Bind (S, ...)

Listen (s, ...)

Fork ()

After you fork yourself a few times, each process blocks in the Accept () function here

for (;;) {

int client = accept (...); The child process is blocked here.

if (client < 0) continue;

...

}

650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M00/72/54/wKioL1XhTaLg-yBwAAE6dY5WFD0255.jpg "title=" 8196371_1310396920t299.png "alt=" Wkiol1xhtalg-ybwaae6dy5wfd0255.jpg "/>

In older UNIX systems, when a connection arrives, the Accept () is awakened in each of the processes that block it. However, only one of these processes can really accept this connection, and the other process accept will return Eagain surprise cluster result is the system to the user process/thread frequently do invalid scheduling, context switch, system can greatly discount.


Implementation code:

Server-side code:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <errno.h>

#include <sys/socket.h>

#include <arpa/inet.h>

#include <netinet/in.h>

#include <sys/types.h>

#include <unistd.h>

#include <time.h>


#define BUFLEN 1024

#define PIDNUM 3


/******************* one of the concurrent server models: the number of processes is pre-allocated **********************/


static void handle_fork (int sockfd) {

int NEWFD;

struct sockaddr_in c_addr;

Char Buf[buflen];

Socklen_t Len;

time_t now;

while (1) {

len = sizeof (struct sockaddr);

if (NEWFD = Accept (SOCKFD, (struct sockaddr*) &c_addr, &len)) = =-1) {

Perror ("accept");

Exit (errno);

}else

printf ("\n***************** communication begins ***************\n");

printf ("The client that is communicating with you is:%s:%d\n", Inet_ntoa (C_ADDR.SIN_ADDR), Ntohs (C_addr.sin_port));


/****** Processing client Requests *******/

Bzero (Buf,buflen);

Len = recv (newfd,buf,buflen,0);

if (Len >0 &&!strncmp (buf, "Time", 4)) {

Bzero (Buf,buflen);

/* Get the current time of the system */

now = time (NULL);

/*ctime converts the system time to a string, sprintf the converted string to buf*/

sprintf (buf, "%24s\r\n", CTime (&now));

Send System Time *******/

Send (Newfd,buf,strlen (BUF), 0);

}

/* Turn off the communication socket */

Close (NEWFD);

}

}


int main (int argc, char **argv)

{

int sockfd;

struct sockaddr_in s_addr;

unsigned int port, LISTNUM;

pid_t Pid[pidnum];

/* Build socket*/

if ((SOCKFD = socket (af_inet, sock_stream, 0)) = = = 1) {

Perror ("socket");

Exit (errno);

}else

printf ("Socket create success!\n");

/* Set the server port */

if (argv[2])

Port = atoi (argv[2]);

Else

Port = 4567;

/* Set the Listening queue Length */

if (Argv[3])

LISTNUM = Atoi (argv[3]);

Else

LISTNUM = 3;

/* Set up server ip*/

Bzero (&s_addr, sizeof (S_ADDR));

s_addr.sin_family = af_inet;

S_addr.sin_port = htons (port);

if (Argv[1])

S_ADDR.SIN_ADDR.S_ADDR = inet_addr (argv[1]);

Else

S_ADDR.SIN_ADDR.S_ADDR = Inaddr_any;

/* Fix the address and port on the socket */

if (bind (SOCKFD, struct sockaddr*) &s_addr,sizeof (struct sockaddr)) = = =-1) {

Perror ("bind");

Exit (errno);

}else

printf ("Bind success!\n");

/* Listen for local port */

if (listen (sockfd,listnum) = =-1) {

Perror ("Listen");

Exit (errno);

}else

printf ("The server is listening!\n");

/* Handle the connection to the client */

int i = 0;

for (i = 0; i < Pidnum; i++) {

Pid[i] = fork ();

if (pid[i] = = 0)

Handle_fork (SOCKFD);

}

/* Close the socket for the server */

Close (SOCKFD);

return 0;

}


Client code:



#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <errno.h>

#include <sys/socket.h>

#include <arpa/inet.h>

#include <netinet/in.h>

#include <sys/types.h>

#include <unistd.h>

#include <time.h>


#define BUFLEN 1024


int main (int argc, char **argv)

{

int sockfd;

struct sockaddr_in s_addr;

Socklen_t Len;

unsigned int port;

Char Buf[buflen];

/* Build socket*/

if ((SOCKFD = socket (af_inet, sock_stream, 0)) = = = 1) {

Perror ("socket");

Exit (errno);

}else

printf ("Socket create success!\n");


/* Set the server port */

if (argv[2])

Port = atoi (argv[2]);

Else

Port = 4567;

/* Set up server ip*/

Bzero (&s_addr, sizeof (S_ADDR));

s_addr.sin_family = af_inet;

S_addr.sin_port = htons (port);

if (Inet_aton (argv[1], (struct in_addr *) &s_addr.sin_addr.s_addr) = = 0) {

Perror (argv[1]);

Exit (errno);

}

/* Start connecting to the server */

if (Connect (sockfd, struct sockaddr*) &s_addr,sizeof (struct sockaddr)) = =-1) {

Perror ("Connect");

Exit (errno);

}else

printf ("Conncet success!\n");

/****** Buffer Clear 0 *******/

Bzero (Buf,buflen);

strcpy (buf, "time");

/****** Send Message *******/

Send (Sockfd,buf,strlen (BUF), 0);

/****** Buffer Clear 0 *******/

Bzero (Buf,buflen);

/****** Receive Message *******/

Len = recv (sockfd,buf,buflen,0);

if (len > 0)

printf ("Server's system time is:%s\n", buf);

Close (SOCKFD); /* Close Connection */

return 0;

}


This article from "Tech record" blog, declined reprint!

Process Pool Model

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.