nginx进程间的通信
进程间消息传递
共享内存
共享内存还是Linux下提供的最基本的进程间通信方式,它通过mmap和shmget系统调用在内存中创建了一块连续的线性地址空间,而通过munmap或者shmdt系统调用可以释放这块内存。使用共享内存的好处是当多个进程使用同一块共享内存时,在任何一个进程修改了共享内存中的内容后,其他进程通过访问这段共享内存都能够得到修改后的内容。Nginx定义了ngx_shm_t结构体,用于描述一块共享内存,
typedef struct{
//指向共享内存的其实地址
u_char* addr;
//共享内存的长度
size_t size;
//这块共享内存的名称
ngx_str_t name;
//记录日志的ngx_log_t对象
ngx_lot_t* log;
//表示共享内存是否已经分配过的标志位,为1时表示已经存在
ngx_uint_t exists;
} ngx_shm_t;
操作ngx_shm_t结构体的方法有两个:ngx_shm_alloc(基于mmap实现)用于分配新的共享内存,而ngx_shm_free(基于munmap实现)用于释放已经存在的共享内存。
Nginx各进程间共享数据的主要方式就是使用共享内存。一般是由master进程创建,在master进程fork出子进程后,所有的进程开始使用这块内存中的数据。
Nginx频道
ngx_channel_t频道是Nginx master进程与worker进程之间通信的常用工具,它是使用本机套接字实现的。socketpair方法,用于创建父子进程间使用的套接字。int socketpair ( int d, int type, int protocol, int sv[2] );
通常在父子进程之间通信前,会先调用socketpair创建一组套接字,在调用fork方法创建出子进程后,将会在父进程中关闭sv[1]套接字,子进程关闭sv[0]套接字。
ngx_channel_t频道结构体是Nginx定义的master父进程和worker子进程间通信的消息格式。如下所示:
typedef struct{
//传递的TCP消息中的命令
ngx_uint_t command;
//进程ID,一般是发送命令方的进程ID
ngx_pid_t pid;
//表示发送命令方在ngx_processes进程数组间的序号
ngx_int_t slot;
//通信的套接字句柄
ngx_fd_t fd;
} ngx_channel_t;
这个消息的格式之所以如此简单,是因为Nginx仅用这个频道同步master进程与work进程间的状态,这针对command成员已经定义的命令就可以快拿出来,如下所示:
//打开频道,使用频道这种方式通信前必须发送的命令
#define NGX_CMD_OPEN_CHANNEL 1
//关闭已经打开的频道,实际上也就是关闭套接字
#define NGX_CMD_CLOSE_CHANNEL 2
//要求接收方正常地退出进程
#define NGX_CMD_QUIT 3
//要求接收方强制结束进程
#define NGX_CMD_TERMINATE 4
//要求接收方重新打开进程已经打开过的文件
#define NGX_CMD_REOPEN 5
master进程正是通过socketpair产生的套接字发送命令的,即每次要派生一个进程之前都会调用socketpair方法。在Nginx派生子进程的ngx_spawn_proces方法中,会首先派生基于TCP的套接字。
Nginx封装了4个方法: ngx_write_channel,ngx_write_channel, ngx_write_channel和ngx_close_c