開源專案:
如上圖,mediasoup專案使用nodejs作為業務層,c++編寫的worker作為webrtc的任務程序。nodejs和worker之間使用unixsocket作為程序間通訊的手段。
剛開始接觸到mediasoup v3的時候,mediasoup中有段**讓我感到疑惑:
worker程序將描述符3和描述符4作為訊息讀取和寫入的目標,但是worker程序由主程序建立,主程序為了與worker程序通訊必然要為每個worker程序提前建立unixsocket,而worker程序只需繼承自己的unixsocket描述符即可。
主程序建立的描述符必然是依次增加的,例如:0、1、2分別代表標準輸入(stdin),標準輸出(stdout),錯誤輸出(stderr),建立新的描述符時就會從3開始向後累加,子程序越多建立的unixsocket也就越多,描述符的值會越來越大。
每個worker程序理應繼承主程序的描述符,它是如何做到讓每個worker程序都將3、4作為讀寫描述符的呢?
我們都知道nodejs是基於libuv網路庫實現的,為了找到答案,我決定看看libuv底層**。
我從uv_spawn函式開始追蹤,直到看到初始化子程序的函式我就恍然大明白了。
static
void
uv__process_child_init
(const uv_process_options_t* options,
int stdio_count,
int(
*pipes)[2
],int error_fd)
}for
(fd =
0; fd < stdio_count; fd++)}
}if(fd == use_fd)
uv__cloexec_fcntl
(use_fd,0)
;else
fd =
dup2
(use_fd, fd);if
(fd ==-1
)if(fd <=2)
uv__nonblock_fcntl
(fd,0)
;if(close_fd >= stdio_count)
uv__close
(close_fd);}
for(fd =
0; fd < stdio_count; fd++)if
(options->cwd !=
null
&&chdir
(options->cwd))if
(options->flags &
(uv_process_setuid | uv_process_setgid))if
((options->flags & uv_process_setgid)
&&setgid
(options->gid))if
((options->flags & uv_process_setuid)
&&setuid
(options->uid))if
(options->env !=
null
)/* reset signal disposition. use a hard-coded limit because nsig
* is not fixed on linux: it's either 32, 34 or 64, depending on
* whether rt signals are enabled. we are not allowed to touch
* rt signal handlers, glibc uses them internally.
*/for(n =
1; n <
32; n +=1
)/* reset signal mask. */
sigemptyset
(&set)
; err =
pthread_sigmask
(sig_setmask,
&set,
null);
if(err !=0)
execvp
(options->file, options->args)
;uv__write_int
(error_fd,
uv__err
(errno));
_exit
(127);
}#endif
感興趣的同學可以仔細閱讀,這裡我主要解讀一下fcntl(use_fd, f_dupfd, stdio_count);
和fd = dup2(use_fd, fd);
這兩步關鍵操作。
libuv使用dup2函式將子程序整合進來的unixsocket描述符做了一層重定向。
如果想要更加深入地理解libuv和mediasoup的程序機制,建議詳細研究一下libuv建立程序和pipe的流程。
程序間的通訊
程序間的通訊就麻煩一些了,訊號的種類就有 種,可以在終端中輸入kill l檢視!就先說幾個今天剛學的吧 sigint,這個訊號是由硬體產生的,比如按下ctrl c時就會產生這個訊號。sigalrm,這個訊號是由alrm unsigned int arg 函式產生的,就是間隔arg秒時間後產生siga...
程序間的關係
程序間有什麼關係呢?我們都知道使用fork函式建立程序是一次呼叫兩次返回。父程序返回子程序的程序id 非0 子程序返回0值。很顯然,使用fork建立出來的兩個程序是父子關係。那如果兩個程序都是同乙個父程序建立出來的,它們是什麼關係呢?兄弟 關係。那麼,兩個或者多個程序之間,都有什麼關係呢?在介紹程序...
程序間的關係
1.每個程序都會有乙個程序組,程序組是多個程序的集合,多個程序組組成乙個會話。檢視程序組的id,其中每個程序組都有乙個組長,程序組的id就是該程序組長的id號。該程序組是否存在取決於程序組中是否有程序,與程序組長是否結束無關。2.設定程序組的id,如果pid為0,那麼將呼叫該函式的程序的pid設定為...