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;
View Code

 

posted @ 2017-02-17 13:46  丶丨zuoluo  阅读(1955)  评论(0编辑  收藏  举报