January 11th Monday 2010

Nginx(七) 工作进程

进程部份

一切从ngx_worker_process_init()函数开始:

1.先调用ngx_set_environment()函数为本进程设定环境变量,那些环境变量都是从cycle中继承过来的;

2. 有进程执行优先权,则调用setpriority(PRIO_PROCESS, 0, ccf->priority)函数设置优先权;

3. 设置进程可打开最大文件数(setrlimit(RLIMIT_NOFILE, &rlmt));

4. 设置内核转存文件最大长度(setrlimit(RLIMIT_CORE, &rlmt));

5. 支持RLIMIT_SIGPENDING的情况下,设置RLIMIT_SIGPENDING(setrlimit(RLIMIT_SIGPENDING, &rlmt));

6. 支持PR_SET_DUMPABLE时,设置PR_SET_DUMPABLE(prctl(PR_SET_DUMPABLE,1,0,0,0));

7. 换到当前工作的目录下;

8. 清空所有的信号;

9. 清掉监听socket上以前的事件;

10. 调用所的模块的init_process钩子函数;

11. 将其他进程的channel[1]关闭,自己的除外;

12. 将自己的channel[0]关闭;

13. 调用ngx_add_channel_event()函数,给ngx_channel(在ngx_start_worker_processes()函数中,ngx_channel = ngx_processes[s].channel[1];,所以ngx_channel就是进程自身的channel[1],用来读取的socket。)注册一个读事件处理函数;

注:其中重要变量ngx_process_slot的值是在ngx_spawn_process()函数中变动的。其他用到ngx_spawn_process变量,仅是读取其值。

ngx_add_channel_event()函数的主要工作:

1. 取得一个空闲的connection资源;

2. 创建了一个读事件和一个写事件对象,并设置了channel为1;

3. 检查注册的事件是读还是写,分别选用不同的事件对象,安装事件处理函数;

4. epoll事件模式并且ngx_event_actions.add_conn存在时,调用add_conn添加一个connection资源;否则用ngx_event_actions.add添加一个事件对象;

注:在linux环境下,epoll模式仅调用

ngx_channel_handler()函数,这个函数作为事件驱动:

1. 事件对象中的timedout清空;

2. 从事件对象中取得connection对象;

3. 进入循环,调用ngx_read_channel()函数,读取channel对象(还记得什么地方用ngx_write_channel()函数写向子进程写入一个channel对象吗?);

4. NGX_USE_EVENTPORT_EVENT事件标志时,添加读事件;

5. 接下来是检查取得的channel对象中的command,不同的命令不同的处理:

a) NGX_CMD_QUIT: ngx_quit = 1;

b) NGX_CMD_TERMINATE: ngx_terminate = 1;

c) NGX_CMD_REOPEN: ngx_reopen = 1;

d) NGX_CMD_OPEN_CHANNEL: 在ngx_processes[]表中指定项中设置pid和写文件描述符;

e) NGX_CMD_CLOSE_CHANNEL: 关闭ngx_processes[]表中指定表项中的写文件描述符。

“过去酒逢知已千杯少,现在酒逢千杯知已少”。

January 11th Monday 2010

相关文章:

你感兴趣的文章:

标签云: