1. 实现基础的信号处理
sigaction使用前一定内存清零
2. 实现基础的进程模型
wait 等待子进程结束
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "common.h"
#include "serversignal.h"
static volatile sig_atomic_t graceful=0;
int main(int argc, char *argv[])
{
signal_init();
int max_worker= 5;
int child = 0;
while(!graceful&&!child){
if(max_worker>0){
switch(fork()){
case -1:
return -1;
break;
case 0:
child =1;
break;
default:
printf("child creat\n");
max_worker--;
break;
}
}else{
int status =0;
if( -1 != wait(&status)){
max_worker++;
printf("parent wakeup\n");
}
}
}
if(!child){
printf("quit kill children first\n");
kill(0, SIGINT);
sleep(20);
}else{
sleep(5);
printf("child quit\n");
}
return 0;
}
void server_graceful_set(int g)
{
if(g>0){
g=1;
}else{
g=0;
}
graceful=g;
}
int server_graceful_get()
{
return graceful;
}
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "serversignal.h"
#include "server.h"
typedef void (*SIG_HANLDER) (int sig);
struct server_signal{
int sig;
SIG_HANLDER handler;
};
static int signal_handler(int sig);
#define SIG_MAP_GEN(sig, hanlder) {sig, hanlder},
#define SIG_MAP(XX)\
{\
XX(SIGINT, signal_handler)\
XX(SIGHUP, signal_handler)\
XX(0, NULL)\
}\
int signal_init()
{
int index =0;
struct server_signal signals[]=SIG_MAP(SIG_MAP_GEN);
while(signals[index].sig != 0){
struct sigaction act;
memset(&act, 0, sizeof(struct sigaction));
act.sa_handler=(signals[index].handler);
sigemptyset(&act.sa_mask);
sigaction(signals[index].sig, &act, NULL);
index++;
}
return 0;
}
static int signal_handler(int sig)
{
int status=0;
switch(sig){
case SIGINT:
server_graceful_set(1);
break;
case SIGHUP:
printf("sighup\n");
break;
case SIGCHLD:
if(server_graceful_get() == 1){
while(wait(&status)>0){};
}
break;
default:
break;
}
return 0;
}
#ifndef COMMON_H_INCLUDED #define COMMON_H_INCLUDED #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <sys/socket.h> #include <sys/types.h> #include <string.h> typedef enum { true =1, false =0 }boolean; enum logmode{ SERVER_LOG_FILE=0, SERVER_LOG_STDERR }; struct server{ enum logmode svlogmode; }; #define ASSERT(p) do{ if(!p){ printf("assert error at %s , %d .\n", __FILE__, __LINE__); } }while(0) #endif // COMMON_H_INCLUDED
webserver<1>