当前位置: 代码迷 >> 综合 >> Nginx源码初探之基础架构 -进程之间的通信
  详细解决方案

Nginx源码初探之基础架构 -进程之间的通信

热度:43   发布时间:2024-01-25 22:03:24.0

Nginx进程之间的通信机制介绍
进程之间的通信方式如共享内存,套接字、管道、消息队列、信号等。Nginx框架选择了三种方式:共享内存、套接字、信号来访问共享资源。同时Nginx使用了原子操作、信号量、文件锁来实现各个进程直降安全有序的访问资源。
1.共享内存
共享内存是Linux下提供的最基本的进程间的通信方式,他通过mmap或者shmget系统调用内存中创建了一块连续的线性地址空间,通过munmap或者shmdt系统释放内存。Nginx系统封装了ngx_shmtx_t结构体, 用于描述一块共享内存。

1.1数据结构

typedef struct {ngx_atomic_t   lock;
#if (NGX_HAVE_POSIX_SEM)ngx_atomic_t   wait;
#endif
} ngx_shmtx_sh_t;typedef struct {
#if (NGX_HAVE_ATOMIC_OPS)/*宏定义采用原子锁控制共享内存*/ngx_atomic_t  *lock;
#if (NGX_HAVE_POSIX_SEM)/*宏定义采用信号量控制内存共享*/ngx_atomic_t  *wait;ngx_uint_t     semaphore;/*等于1,表示成功初始化信号量了*/sem_t          sem;/*信号量,决定内存是否在进程间共享*/
#endif
#elsengx_fd_t       fd;/*文件锁控制共享内存*/u_char        *name;
#endifngx_uint_t     spin;
} ngx_shmtx_t;

1.2.创建共享内存

ngx_int_t
ngx_shmtx_create(ngx_shmtx_t *mtx, ngx_shmtx_sh_t *addr, u_char *name)
{mtx->lock = &addr->lock;if (mtx->spin == (ngx_uint_t) -1) {return NGX_OK;}mtx->spin = 2048;#if (NGX_HAVE_POSIX_SEM)mtx->wait = &addr->wait;if (sem_init(&mtx->sem, 1, 0) == -1) {ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno,"sem_init() failed");} else {mtx->semaphore = 1;}#endifreturn NGX_OK;
}

2.Nginx频道
ngx_channel_t频道使用套接字实现(socketpair 方法),它用于创建父子进程间使用的套接字,是Nginx master进程和worker进程之间通信的工具。
2.1 chanel结构体

typedef struct {ngx_uint_t  command;/*TCP 消息中的命令*/ngx_pid_t   pid;/*进程ID,一般是发送命令方的进程*/ngx_int_t   slot;/*在ngx_process进程间的序号*/ngx_fd_t    fd;/*通信套接字的句柄*/
} ngx_channel_t;

2.socketpair方法介绍
Nginx工作时master进程会fork出n个worker进程(具有相同的工作逻辑和功能)。父进程复杂监听信号,通过 socket pair把信号传递给子进程(子进程之间一般不通信)。
3.信号
信号是一种非常短的消息,用于进程之间传递消息。Nginx通过定义ngx_signal_t结构体用于描述接收到信号时的行为。

typedef struct {int     signo;/*需要处理的信号*/char   *signame;/*信号对应的字符串名称*/char   *name;/*这个信号对应着的 Nginx 命令*/void  (*handler)(int signo, siginfo_t *siginfo, void *ucontext);/*收到 signo 信号后就会回调 handler 方法*/
}ngx_signal_t;

 

  相关解决方案