Apache进程池模型

vi common.h

#define MYPORT 8800

#define KEYPATH "/tmp/server"
#define KEYPROJ 'a'

#define START_SERVERS 5
#define MINSPARESERVERS_DFL 5
#define MAXSPARESERVERS_DFL 10
#define MAXCLIENTS_DFL 150

typedef struct node {
        struct node *next;
        pid_t pid;
        int state;
        int reuse;
} Node_t;

#define ST_FREE 0L
#define ST_BUSY 1L

#define IDLE_PID (pid_t)0

struct msgbuf {
        long mtype;
        pid_t pid;
        int state;
};

//#endif

vi server.h

/******************************/

void
ServerJob();

vi server.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "common.h"

extern int sd;
extern int msgid;
static struct msgbuf buf;

static void
NoticeState(int state) {
        buf.mtype=1;
        buf.state=state;
        msgsnd(msgid,&buf,sizeof(buf)-sizeof(long),0);
}

//getsd

void
ServerJob() {
        int i;
        int newsd;
        struct sockaddr_in his_end;
        int his_end_len;
        int ret;

        buf.pid=getpid();

        his_end_len=sizeof(his_end);
        while(1) {
                do {
                        newsd=accept(sd,(struct sockaddr *)&his_end,&his_end_len);
                } while(newsd<0);

                NoticeState(ST_BUSY);

                for(i=0;i<10;i++) {
                        write(newsd,".",1);
                        sleep(1);
                }

                close(newsd);

                NoticeState(ST_FREE);
        }
}

vi main.c

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/wait.h>
#include "server.h"
#include "common.h"

int msgid=0;
int sd=0;
Node_t head={NULL,IDLE_PID,ST_FREE,0};
int nBusy=0;
int nFree=0;

static int
getMsg(void);

static int
getSocket();

static int
ReuseAdd_pid(Node_t *ptr,pid_t pid);

static int
SetState_pid(Node_t *ptr,pid_t pid,int state);

static int
DeleteNode_pid(Node_t *ptr,pid_t pid);

static int
DeleteNode_anyfree(Node_t *ptr);

static int
AddNode(Node_t *ptr);

static void
DumpList(Node_t *head);

static void
ScanList(Node_t *head);

static void
chld_handle(int s) {
        pid_t pid;

        while(pid=waitpid(-1,NULL,WNOHANG)>0) {
                DeleteNode_pid(&head,pid);
        }
}

int
main() {
        int i,ret;
        struct msgbuf buf;

        signal(SIGCHLD,chld_handle);

        msgid=getMsg();
        if(msgid==-1) {
                perror("Get msg queue");
                exit(-1);
        }

        sd=getSocket();
        if(sd==-1) {
                perror("Get net socket");
                exit(-1);
        }

        for(i=0;i<START_SERVERS;i++) {
                ret=AddNode(&head);
                if(ret==-1) {
                        fprintf(stderr,"AddNode failed.\n");
                } else {
                }
        }

        // add test
        DumpList(&head);

        while(1) {
                ret=msgrcv(msgid,&buf,sizeof(buf)-sizeof(long),1,0);
                fprintf(stderr,"Got a msg from %d\n",buf.pid);
                if(ret>0) {
                        SetState_pid(&head,buf.pid,buf.state);
                }
                ScanList(&head);
#ifndef RELEASE
                DumpList(&head);
#endif
        }
}

static int
getMsg() {
        key_t key;

        key=ftok(KEYPATH,KEYPROJ);
        if(key==-1) {
                perror("ftok()");
                return -1;
        }

        msgid=msgget(key,IPC_CREAT|0600);
        if(msgid==-1) {
                perror("msgget()");
                return -1;
        } return msgid;
}

static int
getSocket() {
        int ret;
        struct sockaddr_in my_end;

        sd=socket(PF_INET,SOCK_STREAM,0);
        if(sd==-1) {
                perror("socket()");
                return -1;
        }

        int val=1;
        ret=setsockopt(sd,SOL_SOCKET,SO_REUSEADDR,&val,sizeof(val));
        /*
        if(ret==-1) {
                perror("setsockopt()");
                return -1;
        }
        */

        my_end.sin_family=AF_INET;
        my_end.sin_port=htons(MYPORT);
//      my_end.sin_addr.s_addr=inet_addr();
        my_end.sin_addr.s_addr=INADDR_ANY;

        ret=bind(sd,(struct sockaddr *)&my_end,sizeof(my_end));
        if(ret==-1) {
                perror("bind()");
                return -1;
        }

        ret=listen(sd,10);
        if(ret==-1) {
                perror("listen()");
                return -1;
        }

        return sd;
}

static int
AddNode(Node_t *ptr) {
        pid_t pid;
        Node_t *temp;

        temp=(Node_t *)malloc(sizeof(Node_t));
        if(temp==NULL) {
                perror("malloc()");
                return -1;
        }

        pid=fork();
        if(pid==-1) {
                perror("fork()");
                free(temp);
                return -1;
        }

        if(pid==0) {
                free(temp);
        /* TODO: Delete link table */
                ServerJob();
        }
        temp->pid=pid;
        temp->state=ST_FREE;
        temp->reuse=0;
        temp->next=ptr->next;
        ptr->next=temp;
        nFree++;

        return pid;
}

static void
DumpList(Node_t *head) {
        Node_t *temp;

        temp=head->next;
        while(temp!=NULL) {
                if(temp->state==ST_BUSY) {
                        printf("<%d>",temp->pid);
                } else {
                        printf("%d ",temp->pid);
                }
                temp=temp->next;
        }
        printf("\n");
        printf("nFree=%d\tnBusy=%d\n\n",nFree,nBusy);

        return;
}

static int
DeleteNode_pid(Node_t *ptr,pid_t pid) {
        Node_t *temp,*temp_next;
        int mark=0;

        temp=ptr;
        temp_next=temp->next;
        while(temp_next!=NULL) {
                if(temp_next->pid==pid) {
                        mark=1;
                        temp->next=temp_next->next;
                        kill(temp_next->pid,SIGTERM);
                        if(temp_next->state==ST_FREE) {
                                nFree--;
                        } else {
                                nFree++;
                        }
                        free(temp_next);
                        break;
                }
                temp=temp_next;
                temp_next=temp->next;
        }
        if(mark) {
                return 0;
        } else {
                return -1;
        }
}

static int
DeleteNode_anyfree(Node_t *ptr) {
        int mark=0;
        Node_t *temp,*temp_next;

        temp=ptr;
        temp_next=temp->next;
        while(temp_next!=NULL) {
                if(temp_next->state==ST_FREE) {
                        mark=1;
                        temp->next=temp_next->next;
                        kill(temp_next->pid,SIGTERM);
                        nFree--;
                        free(temp_next);
                        break;
                }
                temp=temp_next;
                temp_next=temp->next;
        }
        if(mark) {
                return 0;
        } else {
                return -1;
        }
}

static int
SetState_pid(Node_t *ptr,pid_t pid,int state) {
        Node_t *temp;
        int mark=0;

        temp=ptr->next;
        while(temp!=NULL) {
                if(temp->pid==pid) {
                        mark=1;
                        if(state==ST_FREE) {
                                nFree++;
                                if(temp->state==ST_BUSY) {
                                        nBusy--;
                                }
                        } else if(state==ST_BUSY) {
                                nBusy++;
                                if(temp->state==ST_FREE) {
                                        nFree--;
                                }
                        } else {
                                fprintf(stderr,"Unknown state.\n");
                                return -1;
                        }
                        temp->state=state;
                        break;
                }
                temp=temp->next;
        }
        if(mark) {
                return 0;
        } else {
                return -1;
        }
}

static void
ScanList(Node_t *head) {
        int i,ret,delta;
        Node_t *temp;
        int tnFree=0,tnBusy=0;
        sigset_t now,old;

        sigemptyset(&now);
        sigaddset(&now,SIGCHLD);
        sigprocmask(SIG_BLOCK,&now,&old);

        temp=head->next;
        while(temp!=NULL) {
                ret=kill(temp->pid,0);
                if(ret==-1) {
                        fprintf(stderr,"Lame node found,delete it.\n");
                        DeleteNode_pid(temp,temp->pid);
                } else {
                        if(temp->state==ST_BUSY) {
                                tnBusy++;
                        } else {
                                tnFree++;
                        }
                }
                temp=temp->next;
        }

        if(nBusy!=tnBusy) {
                fprintf(stderr,"nBusy corrected(%d).\n",tnBusy);
                nBusy=tnBusy;
        }

        if(nFree!=tnFree) {
                fprintf(stderr,"nFree corrected(%d).\n",tnFree);
                nFree=tnFree;
        }

        if(nFree<MINSPARESERVERS_DFL) {
                delta=MINSPARESERVERS_DFL-nFree;
                if(delta>MAXCLIENTS_DFL-nFree-nBusy) {
                        delta=delta>MAXCLIENTS_DFL-nFree-nBusy;
                }
                fprintf(stderr,"%d proces needed to be added.\n",delta);
                for(;delta>0;delta--)
                        AddNode(head);
                //      AddNode(&head);
       // } else if(nFree>MINSPARESERVERS_DFL) {
        } else if(nFree>MAXSPARESERVERS_DFL) {
                delta=nFree-MAXSPARESERVERS_DFL;
                fprintf(stderr,"%d proces needed to be deleted.\n",delta);
                for(;delta>0;delta--) {
                        DeleteNode_anyfree(head);
                //      DeleteNode_anyfree(&head);
                }
        } else {
                /* No adjust needed. */
        }

        sigprocmask(SIG_SETMASK,&old,NULL);

        return;
}

你可能感兴趣的:(struct,socket,kill,null,null,delete)