nginx的worker-master启动之worker进程

时间:2021-05-27 16:25:02

嗯,这篇文章主要讲worker进程,从哪里开始讲呢,在上面的文章我们已经知道在master进程中会调用start_worker_process函数开启worker进程,在该函数中会调用ngx_spawn_process函数真正的创建worker进程,那么就从ngx_spawn_process函数开始吧(src/os/unix/Ngx_process.c):

其实函数还是比较简单的,首先是:

//找到ngx_processes中一个空闲的位置,用来放置fork出来的进程的信息
if (respawn >= 0) {
s = respawn;

} else {
for (s = 0; s < ngx_last_process; s++) {
if (ngx_processes[s].pid == -1) {
break;
}
}
//达到最大的进程限制了
if (s == NGX_MAX_PROCESSES) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
"no more than %d processes can be spawned",
NGX_MAX_PROCESSES);
return NGX_INVALID_PID;
}
}
这部分代码主要是在全局变量ngx_processes中找到一个空闲的位置,用来保存待会创建的子进程的信息。


接下来的部分是创建socketpair,用于进程间的通信,这里就不细写了,以后写进程间通信的部分再写吧。好吧接下来就是等了好久的fork函数了:

 pid = fork();

switch (pid) {

case -1:
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
"fork() failed while spawning \"%s\"", name);
ngx_close_channel(ngx_processes[s].channel, cycle->log);
return NGX_INVALID_PID;

case 0: //子进程,开始执行它的函数
ngx_pid = ngx_getpid();
proc(cycle, data); //执行work进程的进程函数
break;

default:
break;
}
子进程直接运行传进来的worker进程的运行函数即可了,该函数为ngx_worker_process_cycle,定义在Ngx_process_cycle.c当中,现在来看这个函数吧,好吧,首先是一句代码:
ngx_process = NGX_PROCESS_WORKER;   //修改该子进程全局变量ngx_process的值表示为worker进程
这里用来表示当前进程是worker进程。
worker进程的运行函数首先会调用ngx_worker_process_init函数初始化,那么还是先看这个函数吧。

其实这个函数重要的代码页没多少,首先是获取ngx_core_module模块的配置,然后通过它设置一些类似于优先级的东西。然后又一段比较重要的代码:

//在这里进行各个模块的初始化,这样保证每一个fork出来的子进程都可以访问模块
for (i = 0; ngx_modules[i]; i++) {
if (ngx_modules[i]->init_process) {
if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) {
/* fatal */
exit(2);
}
}
}
因为这里已经是在worker子进程当中运行了,所以每个子进程都会从master进程中继承全局变量ngx_modules,当然还有许多的其他变量。这里会循环遍历所有的模块,调用它们的init_process函数,这样可以保证它们在当前worker进程中可以用, ngx_worker_process_init剩下的代码就是关于设置进程间通信的了,以后再说。


现在回到ngx_worker_process_cycle函数,当初始化完成了以后,那么就可以直接进入worker进程的主循环了,处理一些从master传过来的命令,具体命令式怎么传过来的以后再讲。接着解释调用很重要的函数ngx_process_events_and_timers来处理所有的事件以及定时。

好了,worker进程也差不多了,下面的文章讲进程间的通信。