欧美日韩精品在线,国内精品久久久久久久久,一级毛片恃级毛片直播,清纯唯美亚洲综合欧美色

Nginx的master和worker進(jìn)程間的通信_Web服務(wù)器教程

編輯Tag賺U幣
教程Tag:nginx添加

本文就大概看一下master進(jìn)程和worker進(jìn)程之間是如何使用 channel來完成通信的。這部分實(shí)現(xiàn)的源碼主要分布于src/os/unix/channel.h和channel.c兩個(gè)文件中。實(shí)現(xiàn)極其簡單,沒 有什么復(fù)雜的邏輯。下面,我繪制了一個(gè)簡單的master進(jìn)程和worker進(jìn)程間的關(guān)系,圖中的箭頭符號指出數(shù)據(jù)是由master進(jìn)程傳給worker 進(jìn)程,而沒有從worker到master;這是因?yàn)閏hannel不是一個(gè)普通的數(shù)據(jù)傳輸管道,在Nginx中它僅僅是用著master發(fā)送指令給 worker的一個(gè)管道,master借此channel來告訴worker進(jìn)程該做什么了,worker卻不需要告訴master該做什么,所以是一個(gè) 單向的通道。
 

master進(jìn)程每次發(fā)送給worker進(jìn)程的指令用如下一個(gè)結(jié)構(gòu)來完成封裝:

 

typedef struct {
ngx_uint_t command;
ngx_pid_t pid;
ngx_int_t slot;
ngx_fd_t fd;
} ngx_channel_t;

這個(gè)結(jié)構(gòu)中的4個(gè)字段分別是發(fā)送的指令、worker進(jìn)程的pid、worker進(jìn)程的slot(在ngx_proecsses中的索引)及一個(gè)文 件描述符。master進(jìn)程可能會(huì)將一個(gè)打開的文件描述符發(fā)送給worker進(jìn)程進(jìn)行讀寫操作,那么此時(shí)就需要填寫fd這個(gè)字段了。worker進(jìn)程在收 到一個(gè)這樣的結(jié)構(gòu)數(shù)據(jù)后,通過判斷command的值來采取相應(yīng)的動(dòng)作;command就是master給worker下達(dá)的命令。

master進(jìn)程用于處理SIGCHLD信號的函數(shù)ngx_reap_children中就有向worker進(jìn)程發(fā)送關(guān)閉channel的指令,我們看看這個(gè)例子是怎么做的。

    ch.command = NGX_CMD_CLOSE_CHANNEL;
ch.fd = -1;
ch.pid = ngx_processes[i].pid;
ch.slot = i;
ngx_write_channel(ngx_processes[n].channel[0],
&ch, sizeof(ngx_channel_t), cycle->log);

這幾行代碼是我從ngx_reap_children函數(shù)中拼湊起來的,所以看上去好像有點(diǎn)奇怪,不那么順暢;但卻清晰的給我們展現(xiàn)了master 進(jìn)程怎么給一個(gè)worker進(jìn)程發(fā)送指令,此處發(fā)送的指令時(shí)NGX_CMD_CLOSE_CHANNEL。發(fā)送指令的函數(shù) ngx_write_channel是利用sendmsg來完成,《Unix網(wǎng)絡(luò)編程》可以詳細(xì)了解sendmsg。

worker進(jìn)程在調(diào)用ngx_worker_process_init進(jìn)行初始化的時(shí)候,使用了如下兩行代碼將channel放到epoll等事件處理模塊中。

    if (ngx_add_channel_event(cycle, ngx_channel, NGX_READ_EVENT,
ngx_channel_handler)
== NGX_ERROR)
{
/* fatal */
exit(2);
}

當(dāng)master進(jìn)程發(fā)來指令后,就調(diào)用ngx_channel_handler函數(shù)進(jìn)行事件的響應(yīng)。下面濃縮的代碼給出了ngx_channel_handler所做的事情。

		/*
讀出master進(jìn)程發(fā)送給過來的指令數(shù)據(jù), ngx_read_channel
是利用recvmsg實(shí)現(xiàn),詳細(xì)介紹見《unix網(wǎng)絡(luò)編程》
*/
n = ngx_read_channel(c->fd, &ch, sizeof(ngx_channel_t), ev->log);
/*
判斷command的值,從而采取具體的動(dòng)作,代碼意圖都寫得很明顯,
就不在這里多說了。
*/
switch (ch.command) {
case NGX_CMD_QUIT:
ngx_quit = 1;
break;
case NGX_CMD_TERMINATE:
ngx_terminate = 1;
break;
case NGX_CMD_REOPEN:
ngx_reopen = 1;
break;
case NGX_CMD_OPEN_CHANNEL:
ngx_processes[ch.slot].pid = ch.pid;
ngx_processes[ch.slot].channel[0] = ch.fd;
break;
case NGX_CMD_CLOSE_CHANNEL:
if (close(ngx_processes[ch.slot].channel[0]) == -1) {
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
"close() channel failed");
}
ngx_processes[ch.slot].channel[0] = -1;
break;
}

Nginx中關(guān)于整個(gè)channel的實(shí)現(xiàn)就這么簡單,沒有什么多余的事情。

來源:網(wǎng)絡(luò)搜集//所屬分類:Web服務(wù)器教程/更新時(shí)間:2013-04-14
相關(guān)Web服務(wù)器教程