nginx 父子进程通信 channel

来源:互联网 发布:球球大作战刷观战软件 编辑:程序博客网 时间:2024/06/05 19:50

        nginx 中利用socketpair()函数,创建一对相互连接的socket,实现父子进程的通信。 下面分析下整个过程:

 

一  创建

       在子进程创建之前,需要创建这样一对连接:  ngx_spawn_process函数(ngx_process.c中)

 

二 创建子进程

     接着会通过fork创建子进程,在子进程中,会调用ngx_worker_process_init 函数(ngx_process_cycle.c)

 

channel[0] 是用来发送信息的,channel[1]是用来接收信息的。那么对自己而言,它需要向其他进程发送信息,需要保留其它进程的channel[0], 关闭channel[1]; 对自己而言,则需要关闭channel[0]。 最后把ngx_channel放到epoll中,从第一部分中的介绍我们可以知道,这个ngx_channel实际就是自己的 channel[1]。这样有信息进来的时候就可以通知到了。

 

三 实现子进程自己的通信

       子进程创建的时候,父进程的东西都会被子进程继承,所以后面创建的进程能够得到前面进程的channel信息,直接可以和他们通信,那么前面创建的进程如何知道后面的进程信息呢? 很简单,既然前面创建的进程能够接受消息,那么我就发个信息告诉他后面的进程的channel,并把信息保存在channel[0]中,这样就可以相互通信了。

  ngx_pass_open_channel函数中实现(ngx_process_cycle.c)

 

 

我们来看看 ngx_write_channel

 

 

其实就是复制信息,在发送。我们再看看接受到信息的那段如何处理:ngx_chanel_read 函数

先接受信息,再复制信息,下面就是真正的处理了 ngx_channel_handler函数中(ngx_process_cycle.c)

 


            ngx_processes[ch.slot].pid = ch.pid;
            ngx_processes[ch.slot].channel[0] = ch.fd;

就是在对应的位置上复制pid和fd,下次向往哪个进程发信息的时候,直接发到 ngx_process[目标进程].channel[0]

 

 

四 父进程

     对于父进程而言,他知道所有进程的channel[0], 直接可以向子进程发送命令。

 

 

疑问: 父进程的channel[1]没有关闭,那么是不是子进程A向B发送信息的时候,父进程也能收到?知道了高手指导下,谢谢