父进程waitpid子进程的一般实现

本文深入探讨了Web后台开发中prefork进程模型的主进程如何通过监听SIGCHLD信号、创建管道、调用select睡眠等待、回收僵尸进程以及根据需要重启子进程来实现高效的工作流程。以gunicorn为例,详细解析其信号处理逻辑,并与PHP-FPM进行对比,提供了一种统一信号处理的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

web后台开发中很多框架都是prefork的进程模型的, 包括 php-fpm / flup / gunicorn 等等由主进程 fork 
出一堆工作进程, 主进程监督工作进程的存活状态和数量,按照需要重启工作进程. 主进程的主要工作: 1)
回收僵尸子进程 2)重启子进程(重启策略看需求),逻辑比较简单,我们以gunicorn 为例 简单看一下代码


1. 主进程监听SIGCHLD信号, 创建管道, 调用select睡眠等待管道中的消息


2. 收到信号时,调用waitpid回收僵尸进程,存活进程数减一,向管道中写消息,从而唤醒主进程主循环select操作返回


3. 主进程的主循环中收到信号后 select  返回, 检查是否需要重启子进程, 处理完后继续睡眠



gunicorn把SIGCHLD和其他信号区分出来,个人感觉统一起来比较好即: 主进程收到信号后,同一将信号
写入队列并唤醒主循环select调用, select 返回后read出信号类型, 根据信号不通做相应的处理,如果
信号为SIGCHLD此时再进行waitpid和重启子进程的处理.  
可以参照下php-fpm(fpm_signals.c\fpm_events.c)的处理:

//注册信号,创建管道
int fpm_signals_init_main()  

void fpm_event_loop(int err)
{
   //将管道读时间加入到事件循环中
   //fpm_event_set(&signal_fd_event, fpm_signals_get_fd(), FPM_EV_READ, &fpm_got_signal, NULL);   
   //ret = module->wait(fpm_event_queue_fd, timeout);  //等待事件发生
}

//信号管道可读的的回调,读取事件类型并作相应的处理
static void fpm_got_signal(struct fpm_event_s *ev, short which, void *arg) 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值