NGINX----源码阅读---ngx_start_worker_processes(worker进程启动方法)
2017-02-17 13:46
387 查看
在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,不知道干啥的,一会儿看下。
ngx_spawn_process(cycle, ngx_worker_process_cycle,(void *) (intptr_t) i, "worker process", type);
1.变量初始化
2.首先找到ngx_processes列表中是否有已经关掉的进程pid=-1,有的话则继续利用。
3.如果当前启动的进程数大于最大进程数则报错,退出。
4.初始化子父进程通信的消息队列
5.pid = fork();
fork子进程。
6.子进程执行,父进程退出。
proc(cycle, data);
proc指向的函数是 ngx_worker_process_cycle
data对应worker编号
7.进程进行状态的设置
View Code
其中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;
View Code
相关文章推荐
- nginx 源码学习笔记(十六)—— ngx_start_worker_processes子进程创建
- nginx 源码学习笔记(十六)—— ngx_start_worker_processes子进程创建
- nginx 源码学习笔记(十七)—— ngx_worker_process_cycle子进程执行
- NGINX----源码阅读---worker进程都干了啥
- [置顶] nginx源码阅读(五).worker进程的工作循环
- Nginx源码阅读(ngx_worker_process_cycle)
- nginx 源码学习笔记(十七)—— ngx_worker_process_cycle子进程执行
- nginx 源码学习笔记(十七)—— ngx_worker_process_cycle子进程执行
- Nginx源码阅读(worker进程处理http请求流程)
- nginx源码学习(四)worker进程的启动
- nginx 源码学习 ngx_worker_process_cycle子进程执行
- nginx源码分析--master和worker进程模型
- Nginx源码分析-进程管理之worker进程
- Nginx源码分析:3张图看懂启动及进程工作原理
- Nginx源码分析—worker进程的创建
- Android系统源码阅读(4):Service在新进程中启动过程
- Nginx源码分析-master和worker进程间的通信
- Android系统源码阅读(3):子Activity在进程内的启动过程
- Flask源码阅读(二)——启动服务器(run方法)
- nginx源码分析(12)-进程启动分析(2)