在mater进程首先通过调用ngx_start_worker_processes(cycle, ccf->worker_processes,NGX_PROCESS_RESPAWN);函数启动worker进程。
其中ccf->worker_processes代表启动的worker进程个数
1.变量声明。
ngx_int_t i;
ngx_channel_t ch;2.打印一条启动worker进程的日志。
ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes");
3.循环调用ngx_spawn_process函数启动worker进程。并初始化ngx_channel_t ch;
ngx_pass_open_channel,不知道干啥的,一会儿看下。
1 for (i = 0; i < n; i++) { 2 3 ngx_spawn_process(cycle, ngx_worker_process_cycle, 4 (void *) (intptr_t) i, "worker process", type); 5 6 ch.pid = ngx_processes[ngx_process_slot].pid; 7 ch.slot = ngx_process_slot; 8 ch.fd = ngx_processes[ngx_process_slot].channel[0]; 9 10 ngx_pass_open_channel(cycle, &ch);11 }
ngx_spawn_process(cycle, ngx_worker_process_cycle,(void *) (intptr_t) i, "worker process", type);
1.变量初始化
u_long on;ngx_pid_t pid;ngx_int_t s;
2.首先找到ngx_processes列表中是否有已经关掉的进程pid=-1,有的话则继续利用。
3.如果当前启动的进程数大于最大进程数则报错,退出。
4.初始化子父进程通信的消息队列
1 //NGX_PROCESS_DETACHED暂时不知道做什么的 2 if (respawn != NGX_PROCESS_DETACHED) { 3 4 /* Solaris 9 still has no AF_LOCAL */ 5 //打开全双工队列,用于子进程和父进程的通信。 6 if (socketpair(AF_UNIX, SOCK_STREAM, 0, ngx_processes[s].channel) == -1) 7 { 8 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, 9 "socketpair() failed while spawning \"%s\"", name);10 return NGX_INVALID_PID;11 }12 13 ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,14 "channel %d:%d",15 ngx_processes[s].channel[0],16 ngx_processes[s].channel[1]);17 //ioctl控制消息队列的访问方式,具体还不懂。18 if (ngx_nonblocking(ngx_processes[s].channel[0]) == -1) {19 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,20 ngx_nonblocking_n " failed while spawning \"%s\"",21 name);22 ngx_close_channel(ngx_processes[s].channel, cycle->log);23 return NGX_INVALID_PID;24 }25 //同上26 if (ngx_nonblocking(ngx_processes[s].channel[1]) == -1) {27 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,28 ngx_nonblocking_n " failed while spawning \"%s\"",29 name);30 ngx_close_channel(ngx_processes[s].channel, cycle->log);31 return NGX_INVALID_PID;32 }33 34 on = 1;35 if (ioctl(ngx_processes[s].channel[0], FIOASYNC, &on) == -1) {36 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,37 "ioctl(FIOASYNC) failed while spawning \"%s\"", name);38 ngx_close_channel(ngx_processes[s].channel, cycle->log);39 return NGX_INVALID_PID;40 }41 42 if (fcntl(ngx_processes[s].channel[0], F_SETOWN, ngx_pid) == -1) {43 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,44 "fcntl(F_SETOWN) failed while spawning \"%s\"", name);45 ngx_close_channel(ngx_processes[s].channel, cycle->log);46 return NGX_INVALID_PID;47 }48 49 if (fcntl(ngx_processes[s].channel[0], F_SETFD, FD_CLOEXEC) == -1) {50 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,51 "fcntl(FD_CLOEXEC) failed while spawning \"%s\"",52 name);53 ngx_close_channel(ngx_processes[s].channel, cycle->log);54 return NGX_INVALID_PID;55 }56 57 if (fcntl(ngx_processes[s].channel[1], F_SETFD, FD_CLOEXEC) == -1) {58 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,59 "fcntl(FD_CLOEXEC) failed while spawning \"%s\"",60 name);61 ngx_close_channel(ngx_processes[s].channel, cycle->log);62 return NGX_INVALID_PID;63 }64 65 ngx_channel = ngx_processes[s].channel[1];66 67 } else {68 ngx_processes[s].channel[0] = -1;69 ngx_processes[s].channel[1] = -1;70 }
5.pid = fork();
fork子进程。
6.子进程执行,父进程退出。
proc(cycle, data);
proc指向的函数是 ngx_worker_process_cycle
data对应worker编号
7.进程进行状态的设置
1 ngx_processes[s].proc = proc; 2 ngx_processes[s].data = data; 3 ngx_processes[s].name = name; 4 ngx_processes[s].exiting = 0; 5 6 switch (respawn) { 7 8 case NGX_PROCESS_NORESPAWN: 9 ngx_processes[s].respawn = 0;10 ngx_processes[s].just_spawn = 0;11 ngx_processes[s].detached = 0;12 break;13 14 case NGX_PROCESS_JUST_SPAWN:15 ngx_processes[s].respawn = 0;16 ngx_processes[s].just_spawn = 1;17 ngx_processes[s].detached = 0;18 break;19 20 case NGX_PROCESS_RESPAWN:21 ngx_processes[s].respawn = 1;22 ngx_processes[s].just_spawn = 0;23 ngx_processes[s].detached = 0;24 break;25 26 case NGX_PROCESS_JUST_RESPAWN:27 ngx_processes[s].respawn = 1;28 ngx_processes[s].just_spawn = 1;29 ngx_processes[s].detached = 0;30 break;31 32 case NGX_PROCESS_DETACHED:33 ngx_processes[s].respawn = 0;34 ngx_processes[s].just_spawn = 0;35 ngx_processes[s].detached = 1;36 break;37 }38 39 if (s == ngx_last_process) {40 ngx_last_process++;41 }42 43 return pid;