/*
* 用来测试lighttpd的一些模型。
*/
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#define NUM 5
static volatile sig_atomic_t srv_shutdown = 0;
static volatile sig_atomic_t graceful_shutdown = 0;
static volatile sig_atomic_t handle_sig_alarm = 1;
static volatile sig_atomic_t handle_sig_hup = 0;
static volatile sig_atomic_t forwarded_sig_hup = 0;
static void signal_handler(int sig) {
switch (sig) {
case SIGTERM:
srv_shutdown = 1;
break;
case SIGINT:
if (graceful_shutdown)
srv_shutdown = 1;
else
graceful_shutdown = 1;
break;
case SIGALRM:
handle_sig_alarm = 1;
break;
case SIGHUP:
handle_sig_hup = 1;
break;
case SIGCHLD:
break;
}
}
/*
* 该模型是lighttpd的主进程模型。
*
* 该模型的主要优点是:
* 1)生成一个进程池来为客户端服务
* 2) 若进程池中的某个进程死掉,它会回收该子进程的资源并且继续生成一个新的子进程
* 3) 用进程池来作为服务器模型,最大的好处是,不用每次来一个客户端就重新生成一个子进程为之服务
* 4) 而是有子进程等待在这里,客户端一来,就可以得到响应,该模型是一个很好的模型,可用于对每个客户端进行一样的服务流程的服务器端。
*
*/
int
main(int argc, char *argv[])
{
int num_childs = NUM;
int child;
/* ignore the SIGPIPE from sendfile() */
signal(SIGPIPE, SIG_IGN);
signal(SIGUSR1, SIG_IGN);
signal(SIGALRM, signal_handler);
signal(SIGTERM, signal_handler);
signal(SIGHUP, signal_handler);
signal(SIGCHLD, signal_handler);
signal(SIGINT, signal_handler);
if (num_childs > 0) {
child = 0;
/*
* 不是child,而且也没有被关闭,则进入while循环中
*/
while (!child && !srv_shutdown && !graceful_shutdown) {
if (num_childs > 0) { /* 还可以继续生成子进程 */
fprintf(stderr, "fork child now ...\n");
switch(fork()) {
case -1:
return -1;
case 0: // child
child = 1;
break;
default: // parent
num_childs--;
break;
}
} else {
int status;
// 若有子进程退出,主程序在阻塞在这里回收资源
// 并把num_childs加1,回到循环再生成新的子进程,
// 这样就可以始终保持有NUM个子进程在运行。
fprintf(stderr, "all child ok! waiting child exit. \n");
if (-1 != wait(&status)) {
num_childs++;
} else { //wait error
switch (errno) {
case EINTR:
kill(0, SIGHUP);
break;
default :
break;
}
}
}
}
/* this is parent exit point */
if (!child) {
if (graceful_shutdown)
kill(0, SIGINT);
return 0;
}
}
/*
* 这里由子进程开始我们的工作
*/
fprintf(stderr, "ppid = %d, pid = %d, num_child=[%d]\n", getppid(), getpid(), num_childs);
if (num_childs == 2) {
fprintf(stderr, "I 2 (pid=[%ld]) start work now ...\n", getpid());
sleep(2);
}
if (num_childs == 3) {
fprintf(stderr, "I 3 (pid=[%ld]) start work now ...\n", getpid());
sleep(4);
}
if (num_childs == 4) {
fprintf(stderr, "I 4 (pid=[%ld]) start work now ...\n", getpid());
sleep(8);
}
if (num_childs == 1) {
fprintf(stderr, "I 1 (pid=[%ld]) start work now ...\n", getpid());
sleep(12);
}
exit(0);
}
* 用来测试lighttpd的一些模型。
*/
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#define NUM 5
static volatile sig_atomic_t srv_shutdown = 0;
static volatile sig_atomic_t graceful_shutdown = 0;
static volatile sig_atomic_t handle_sig_alarm = 1;
static volatile sig_atomic_t handle_sig_hup = 0;
static volatile sig_atomic_t forwarded_sig_hup = 0;
static void signal_handler(int sig) {
switch (sig) {
case SIGTERM:
srv_shutdown = 1;
break;
case SIGINT:
if (graceful_shutdown)
srv_shutdown = 1;
else
graceful_shutdown = 1;
break;
case SIGALRM:
handle_sig_alarm = 1;
break;
case SIGHUP:
handle_sig_hup = 1;
break;
case SIGCHLD:
break;
}
}
/*
* 该模型是lighttpd的主进程模型。
*
* 该模型的主要优点是:
* 1)生成一个进程池来为客户端服务
* 2) 若进程池中的某个进程死掉,它会回收该子进程的资源并且继续生成一个新的子进程
* 3) 用进程池来作为服务器模型,最大的好处是,不用每次来一个客户端就重新生成一个子进程为之服务
* 4) 而是有子进程等待在这里,客户端一来,就可以得到响应,该模型是一个很好的模型,可用于对每个客户端进行一样的服务流程的服务器端。
*
*/
int
main(int argc, char *argv[])
{
int num_childs = NUM;
int child;
/* ignore the SIGPIPE from sendfile() */
signal(SIGPIPE, SIG_IGN);
signal(SIGUSR1, SIG_IGN);
signal(SIGALRM, signal_handler);
signal(SIGTERM, signal_handler);
signal(SIGHUP, signal_handler);
signal(SIGCHLD, signal_handler);
signal(SIGINT, signal_handler);
if (num_childs > 0) {
child = 0;
/*
* 不是child,而且也没有被关闭,则进入while循环中
*/
while (!child && !srv_shutdown && !graceful_shutdown) {
if (num_childs > 0) { /* 还可以继续生成子进程 */
fprintf(stderr, "fork child now ...\n");
switch(fork()) {
case -1:
return -1;
case 0: // child
child = 1;
break;
default: // parent
num_childs--;
break;
}
} else {
int status;
// 若有子进程退出,主程序在阻塞在这里回收资源
// 并把num_childs加1,回到循环再生成新的子进程,
// 这样就可以始终保持有NUM个子进程在运行。
fprintf(stderr, "all child ok! waiting child exit. \n");
if (-1 != wait(&status)) {
num_childs++;
} else { //wait error
switch (errno) {
case EINTR:
kill(0, SIGHUP);
break;
default :
break;
}
}
}
}
/* this is parent exit point */
if (!child) {
if (graceful_shutdown)
kill(0, SIGINT);
return 0;
}
}
/*
* 这里由子进程开始我们的工作
*/
fprintf(stderr, "ppid = %d, pid = %d, num_child=[%d]\n", getppid(), getpid(), num_childs);
if (num_childs == 2) {
fprintf(stderr, "I 2 (pid=[%ld]) start work now ...\n", getpid());
sleep(2);
}
if (num_childs == 3) {
fprintf(stderr, "I 3 (pid=[%ld]) start work now ...\n", getpid());
sleep(4);
}
if (num_childs == 4) {
fprintf(stderr, "I 4 (pid=[%ld]) start work now ...\n", getpid());
sleep(8);
}
if (num_childs == 1) {
fprintf(stderr, "I 1 (pid=[%ld]) start work now ...\n", getpid());
sleep(12);
}
exit(0);
}
来源:http://blog.chinaunix.net/u/28197/showart_2401528.html
作者:jackxiang@向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除
地址:https://jackxiang.com/post/3807/
版权所有。转载时必须以链接形式注明作者和原始出处及本声明!
评论列表