NGINX----源码阅读---ngx_start_worker_processes(worker进程启动方法)
在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;