当然对于进程间大量数据的共享 自然而然的我们采用共享内存。
采用socketpair()函数创造匿名socket 为master process(父进程) 和 work process(子进程) 以及work process 之间的通信。
关于socketpair() 参见这里即可。
先看看nginx process 的定义
ngx_process.h
typedef struct { ngx_pid_t pid; int status; ngx_socket_t channel[2];//这里就是用来存放 socketpair 的两个描述符 ngx_spawn_proc_pt proc; void *data;
在nginx_process.c中
ngx_pid_t ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data, char *name, ngx_int_t respawn) { u_long on; ngx_pid_t pid; ngx_int_t s; ... if (socketpair(AF_UNIX, SOCK_STREAM, 0, ngx_processes[s].channel) == -1) //注意是在fork之前哦 { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "socketpair() failed while spawning \"%s\"", name); return NGX_INVALID_PID; } ... pid=fork(); ...
if (ngx_add_channel_event(cycle, ngx_channel, NGX_READ_EVENT, ngx_channel_handler) //子进程把channel加入到监听事件,ngx_channel_handler为事件响应的回调函数 == NGX_ERROR) {
那么子进程和子进程直接是怎么通信的呢?
实际上子进程work_process之间也是通过这些socket进行通信的 : master父进程每次fork一个新进程的时候都会把这个新进程的信息告知前面已经生成的子进程
在ngx_process_cycle.c中
ngx_pass_open_channel(ngx_cycle_t *cycle, ngx_channel_t *ch) { ngx_int_t i; for (i = 0; i < ngx_last_process; i++) { if (i == ngx_process_slot || ngx_processes[i].pid == -1 || ngx_processes[i].channel[0] == -1) { continue; }
不过截至目前,Nginx并没有子进程向父进程写入信息,子进程间的通信也没有实际用处。
这样子进程直接都有了各自的信息包括socket描述符。这样可以彼此可以通过此完成通信。
参考书籍:《深入剖析Nginx> 高群凯
原文地址:http://blog.csdn.net/qq112928/article/details/25041313