nginx worker進程

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保存的是處理函數

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章