您的位置:首页 > 运维架构 > Nginx

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,不知道干啥的,一会儿看下。

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: