nginx的master和worker进程间的通信
2015-01-23 00:02
507 查看
本文 主要分析master进程和worker进程之间是如何使用channel来完成通信的。这部分实现的代码主要分布在src/os/unix/ngx_channel.c文件中。master进程将数据传给worker进程,用socketpair创建的通道channel[0]将命令发送给worker进程,告诉worker进程要做什么。而worker进程不需要告诉master进程做什么,是一个单向的通道。
master进程每次发送给worker进程的指令用如下的一个结构来完成封装
typedef struct {
ngx_uint_t command;
ngx_pid_t pid;
ngx_int_t slot;
ngx_fd_t fd;
} ngx_channel_t;四个成员分别表示命令、worker进程的pid、worker进程的slot(在ngx_processes数组中的下标)、文件描述符。
worker进程在收到这个的一个结构数据后,通过判断command来作相应的动作。
master进程用于处理SIGCHLD信号的函数ngx_reap_children中就有向worker进程发送关闭channel的指令
worker进程在调用ngx_worker_process_init函数时,通过ngx_add_channel_event将channel放到epoll事件处理模块中。
if (ngx_add_channel_event(cycle, ngx_channel, NGX_READ_EVENT,
ngx_channel_handler)
== NGX_ERROR)
{
/* fatal */
exit(2);
}当收到master进程发过来的命令后,就调用ngx_channel_handler处理,ngx_channel_handler主要做什么呢
switch (ch.command) {
case NGX_CMD_QUIT:
ngx_quit = 1;
break;
case NGX_CMD_TERMINATE:
ngx_terminate = 1;
break;
case NGX_CMD_REOPEN:
ngx_reopen = 1;
break;
case NGX_CMD_OPEN_CHANNEL:
ngx_log_debug3(NGX_LOG_DEBUG_CORE, ev->log, 0,
"get channel s:%i pid:%P fd:%d",
ch.slot, ch.pid, ch.fd);
ngx_processes[ch.slot].pid = ch.pid;
ngx_processes[ch.slot].channel[0] = ch.fd;
break;
case NGX_CMD_CLOSE_CHANNEL:
ngx_log_debug4(NGX_LOG_DEBUG_CORE, ev->log, 0,
"close channel s:%i pid:%P our:%P fd:%d",
ch.slot, ch.pid, ngx_processes[ch.slot].pid,
ngx_processes[ch.slot].channel[0]);
if (close(ngx_processes[ch.slot].channel[0]) == -1) {
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
"close() channel failed");
}
ngx_processes[ch.slot].channel[0] = -1;
break;
}
根据收到的命令类型,采取相应的动作。
整个通信的过程就是如此
master进程每次发送给worker进程的指令用如下的一个结构来完成封装
typedef struct {
ngx_uint_t command;
ngx_pid_t pid;
ngx_int_t slot;
ngx_fd_t fd;
} ngx_channel_t;四个成员分别表示命令、worker进程的pid、worker进程的slot(在ngx_processes数组中的下标)、文件描述符。
worker进程在收到这个的一个结构数据后,通过判断command来作相应的动作。
master进程用于处理SIGCHLD信号的函数ngx_reap_children中就有向worker进程发送关闭channel的指令
worker进程在调用ngx_worker_process_init函数时,通过ngx_add_channel_event将channel放到epoll事件处理模块中。
if (ngx_add_channel_event(cycle, ngx_channel, NGX_READ_EVENT,
ngx_channel_handler)
== NGX_ERROR)
{
/* fatal */
exit(2);
}当收到master进程发过来的命令后,就调用ngx_channel_handler处理,ngx_channel_handler主要做什么呢
switch (ch.command) {
case NGX_CMD_QUIT:
ngx_quit = 1;
break;
case NGX_CMD_TERMINATE:
ngx_terminate = 1;
break;
case NGX_CMD_REOPEN:
ngx_reopen = 1;
break;
case NGX_CMD_OPEN_CHANNEL:
ngx_log_debug3(NGX_LOG_DEBUG_CORE, ev->log, 0,
"get channel s:%i pid:%P fd:%d",
ch.slot, ch.pid, ch.fd);
ngx_processes[ch.slot].pid = ch.pid;
ngx_processes[ch.slot].channel[0] = ch.fd;
break;
case NGX_CMD_CLOSE_CHANNEL:
ngx_log_debug4(NGX_LOG_DEBUG_CORE, ev->log, 0,
"close channel s:%i pid:%P our:%P fd:%d",
ch.slot, ch.pid, ngx_processes[ch.slot].pid,
ngx_processes[ch.slot].channel[0]);
if (close(ngx_processes[ch.slot].channel[0]) == -1) {
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
"close() channel failed");
}
ngx_processes[ch.slot].channel[0] = -1;
break;
}
根据收到的命令类型,采取相应的动作。
整个通信的过程就是如此
相关文章推荐
- Nginx源码分析--master和worker进程间的通信
- Nginx源码分析-master和worker进程间的通信
- Nginx源码分析-master和worker进程间的通信
- 文章8:Nginx中与Master-Worker进程通信有关的内容
- Nginx源码分析-master和worker进程间的通信
- 文章8:Nginx中与Master-Worker进程通信有关的内容
- nginx源码分析--master和worker进程模型
- nginx学习9——修改worker的进程名,修改master的名称,cpu策略,最大并发策略
- nginx的worker-master启动之master进程
- nginx学习笔记四(nginx启动时候的master和worker进程)
- nginx的worker-master启动之worker进程
- Spark中master与worker的进程通信实现
- 关于nginx的master进程可worker进程的概念
- nginx源码分析--框架设计 & master-worker进程模型
- nginx源码分析--master和worker进程模型
- Spark技术内幕:Client,Master和Worker 通信源码解析
- Spark技术内幕:Client,Master和Worker 通信源代码解析
- nginx进程管理之master进程
- Nginx---父子进程通信
- Spark通信--client、master、worker间的通信