1. ioctl一些参数
#include <sys/ioctl.h> ioctl(int fd, int request, ...) fcntl(int fd, int request, ...) // fd 为需要对哪个文件描述符进行操作 // 对fd进行操作的request //... 为参数在nginx 的创建worker 进程时有以下应用场景 1.将描述符设为非阻塞
ioctl(s, FIONBIO, &nb);2.设置文件描述符异步驱动
ioctl(s, FIOASYNC, &on)3.设置文件描述符所属于的pid
fcntl(s, F_SETOWN, ngx_pid)4.子进程任可使用该fd,而用exec 执行的程序关闭fd
fcntl(ngx_processes[s].channel[0], F_SETFD, FD_CLOEXEC)2.socketpair
socketpair(AF_UNIX, SOCK_STREAM, 0, int s[2]) //这个函数,创建出两个fd,从而可以全双工的进行通信可用于父子进程的通信,子进程共享s[2], 父进程关闭一个fd,子进程关闭另一个fd
3. ngx_processes 数据结构 pid保存了该process 的pid channer 保存了该process的fd,其中[0] 为父进程fd 而[1]为子进程fd,
typedef struct { ngx_pid_t pid; int status; ngx_socket_t channel[2]; ngx_spawn_proc_pt proc; void *data; char *name; ...4. 开启流程 1. 从ngx_processes 数组中遍历,如果其中pid为-1,就表示用这个slot作为这个process的存储结构 2. socketpair 生成一对fd对 3. ioctrl fnctrl设置fd属性 4. ngx_process_slot存储当前的slot 5. fork 子进程 6. 子进程进入cycle,等待事件,并 close channel[0] 这边有一点需要注意,因为fork之后,所有的ngx_processes 在子进程也被复制了一份,所以在ngx_last_process 前面的且不等于当前ngx_process_slot的channel[1] fd需要关闭 7. 然后给此fd添加epoll事件 8. 父进程更新ngx_last_process,如果s== ngx_last_process ngx last_process++
其中ngx_event_t 中的data保存的是 connection handler保存的是处理函数
