Nginx學習筆記(七) 建立子程序

2021-09-23 19:40:00 字數 3458 閱讀 5565

ngx_start_worker_processes位於nginx_process_cycle.c中,主要的工作是建立子程序。

在nginx中,master程序和worker程序是通過socketpair函式建立一對socket來實現,父程序與子程序之間的通訊的。而這對socket被儲存在程序結構體ngx_process中的channel[2]陣列中,其中channel[0]為父程序的socket,channel[1]為子程序的socket。

static

void

ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type)

具體分析一下建立子程序的函式,也就是分析ngs_spawn_process:

ngx_pid_t

ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data,

char *name, ngx_int_t respawn)

else

}//超過最大程序限制會報錯

if (s ==ngx_max_processes)

} if (respawn !=ngx_process_detached)

ngx_log_debug2(ngx_log_debug_core, cycle->log, 0

,

"channel %d:%d",

ngx_processes[s].channel[0],

ngx_processes[s].channel[

1]);

//設定非阻塞模式

if (ngx_nonblocking(ngx_processes[s].channel[0]) == -1

)     

if (ngx_nonblocking(ngx_processes[s].channel[1]) == -1

)      //設定非同步模式

on = 1

;

if (ioctl(ngx_processes[s].channel[0], fioasync, &on) == -1)

if (fcntl(ngx_processes[s].channel[0], f_setown, ngx_pid) == -1

)      //若程序執行了exec後,關閉socket

if (fcntl(ngx_processes[s].channel[0], f_setfd, fd_cloexec) == -1)

if (fcntl(ngx_processes[s].channel[1], f_setfd, fd_cloexec) == -1)

ngx_channel = ngx_processes[s].channel[1];

} else

ngx_process_slot =s;

//建立子程序

pid =fork();

switch

(pid)

ngx_log_error(ngx_log_notice, cycle->log, 0, "

start %s %p

", name, pid);

ngx_processes[s].pid =pid;

ngx_processes[s].exited = 0

;    //大於0,說明確定重啟該程序

if (respawn >= 0

)    //設定程序資訊

ngx_processes[s].proc =proc;

ngx_processes[s].data =data;

ngx_processes[s].name =name;

ngx_processes[s].exiting = 0

;    //設定狀態資訊

switch

(respawn)

if (s ==ngx_last_process)

return

pid;

}

接下來,看看nginx是如何在程序間進行通訊的,ngx_pass_open_channel函式:

static

void

ngx_pass_open_channel(ngx_cycle_t *cycle, ngx_channel_t *ch)

ngx_log_debug6(ngx_log_debug_core, cycle->log, 0

,

"pass channel s:%d pid:%p fd:%d to s:%i pid:%p fd:%d",

ch->slot, ch->pid, ch->fd,

i, ngx_processes[i].pid,

ngx_processes[i].channel[

0]);

/*todo: ngx_again

*///把本程序的資訊傳送給每乙個程序的父程序

ngx_write_channel(ngx_processes[i].channel[0],

ch,

sizeof(ngx_channel_t), cycle->log);}}

ngx_write_channel原型:

ngx_int_t

ngx_write_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size, //ch內儲存著本程序的資訊,s是父程序的socket值(channel[0])

ngx_log_t *log)

cmsg;

if (ch->fd == -1

) else

msg.msg_flags = 0

;#else

if (ch->fd == -1

) else

#endif

iov[

0].iov_base = (char *) ch;

iov[

0].iov_len =size;

msg.msg_name =null;

msg.msg_namelen = 0

; msg.msg_iov =iov;

msg.msg_iovlen = 1

; n = sendmsg(s, &msg, 0

);//sendmsg函式,在這裡用於程序間通訊

if (n == -1

) ngx_log_error(ngx_log_alert, log, err,

"sendmsg() failed");

return

ngx_error;

}return

ngx_ok;

}

Nginx學習筆記(七) 建立子程序

ngx start worker processes位於nginx process cycle.c中,主要的工作是建立子程序。在nginx中,master程序和worker程序是通過socketpair函式建立一對socket來實現,父程序與子程序之間的通訊的。而這對socket被儲存在程序結構體n...

nginx 子程序排程

在linux 下,nginx預設是採用多程序模型的,其中乙個是父程序,其他都是子程序,父程序主要做一些全域性初始化 排程等工作,而真正的處理時在子程序中完成的,那麼當乙個請求過來的時候,到底有那個程序去服務呢?我看了 還是沒有找到答案,後來在網上發現了這篇文章 這裡對相關的問題進行總結 一 子程序可...

nginx 子程序排程

在linux 下,nginx預設是採用多程序模型的,其中乙個是父程序,其他都是子程序,父程序主要做一些全域性初始化 排程等工作,而真正的處理時在子程序中完成的,那麼當乙個請求過來的時候,到底有那個程序去服務呢?我看了 還是沒有找到答案,後來在網上發現了這篇文章 這裡對相關的問題進行總結 一 子程序可...