nginx创建work进程是在一个循环中进行的;
static void
ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type)
{
for (i = 0; i < n; i++) {
//省略
ngx_spawn_process(cycle, ngx_worker_process_cycle, NULL,
"worker process", type);
//省略若干
}
}
ngx_pid_t
ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data,
char *name, ngx_int_t respawn)
{
//省略若干
pid = fork();
switch (pid) {
case -1:
//省略若干
case 0:
ngx_pid = ngx_getpid();
proc(cycle, data);
break;
default:
break;
}
//省略若干
}
我们知道,fork在循环中创建子进程的个数是与循环个数n不等的,例如:
for(int i = 0; i < 3; ++i)
{
pid = fork();
if(pid > 0)
{
//父进程
}
else if(pid == 0)
{
//子进程
}
else
{
//error
}
}
上面的代码运行后,总共的进程数为2的3次方个,即8个进程;
那么问题来了,nginx也是通过for来创建work进程,如何控制work进程数目的呢?一值比较疑惑,通过仔细检查代码,发现原因这样的;
nginx在fork后,会运行 proc(cycle, data); proc就是ngx_worker_process_cycle函数;
static void
ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
{
for ( ;; ) {
//省略若干
ngx_worker_process_exit(cycle);
//省略若干
}
}
在这个函数中,如果退出,最终会调用ngx_worker_process_exit(cycle);
static void
ngx_worker_process_exit(ngx_cycle_t *cycle)
{
//省略若干
exit(0);
}
看到没有,这个函数最后会调用exit(0); 直接退出进程;所以整个过程明了了;
总结:
nginx通过for循环来创建进程,是如何控制work进程数目,而没有出现进程泛滥,达到2的n次方个进程的?
原因是:在fork完work进程之后,会调用work进程的死循环函数,在死循环函数中,如果收到quit命令,会直接exit(), 不会再work进程中再次fork work进程的情况出现;