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具體分析一下建立子程序的函式,也就是分析ngs_spawn_process:void
ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type)
ngx_pid_t接下來,看看nginx是如何在程序間進行通訊的,ngx_pass_open_channel函式: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;
}
staticngx_write_channel原型: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_int_tngx_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預設是採用多程序模型的,其中乙個是父程序,其他都是子程序,父程序主要做一些全域性初始化 排程等工作,而真正的處理時在子程序中完成的,那麼當乙個請求過來的時候,到底有那個程序去服務呢?我看了 還是沒有找到答案,後來在網上發現了這篇文章 這裡對相關的問題進行總結 一 子程序可...