国产+高潮+在线,国产 av 仑乱内谢,www国产亚洲精品久久,51国产偷自视频区视频,成人午夜精品网站在线观看

想了解下數(shù)據(jù)是如何分發(fā)到子進程的

萬寶

關(guān)閉端口復用時:在子進程分支之前開始監(jiān)聽
打開端口復用時:在子進程分支之后開始監(jiān)聽
這兩種方式有什么區(qū)別呢
還有就是無論哪種,在分支之后相當于每個進程都在監(jiān)聽同一個端口,那數(shù)據(jù)是怎么分發(fā)到一個進程去處理而不是所有進程都進行處理呢

6276 3 3
3個回答

walkor 打賞

1、不使用端口復用(SO_REUSEPORT),要想讓多個進程監(jiān)聽同一個端口,就需要先讓主進程監(jiān)聽端口,然后fork出子進程,讓子進程繼承主進程的監(jiān)聽socket句柄。

這種情況下當一個tcp鏈接到來時,首先tcp鏈接進入系統(tǒng)內(nèi)核一個隊列里,等待進程去接受(accept系統(tǒng)調(diào)用),如果子進程都是以io復用(select/poll/epoll等)的方式監(jiān)聽socket句柄(workerman就是這樣),那么就會有多個進程被內(nèi)核喚醒同時去爭搶(accept)這個隊列里的tcp鏈接,但是只有一個進程能成功,所以有些進程被白白喚醒,造成一些cpu浪費,這就是所謂的驚群效應。

2、打開端口復用時,主進程不創(chuàng)建監(jiān)聽句柄,每個子進程會自己創(chuàng)建監(jiān)聽句柄(不開端口復用無法做到這一點)

這種情況下當一個tcp鏈接到來時,首先tcp鏈接進入系統(tǒng)內(nèi)核一個隊列里,這時候系統(tǒng)內(nèi)核會自動將tcp鏈接分配給某一個監(jiān)聽句柄的進程,這樣只有一個進程被喚醒去接受(accept),所以沒有驚群效應。也就是說開啟端口復用后內(nèi)核會自動做負載均衡,在短鏈接應用中性能會提升一些(長鏈接應用沒有明顯效果)。

其它相關(guān)鏈接:http://wenda.workerman.net/?/question/179

  • 暫無評論
萬寶

我編輯Worker.php,在acceptConnection中加入調(diào)試內(nèi)容

$new_socket = @stream_socket_accept($socket, 0, $remote_address);
if (!$new_socket) {
    echo 'my pid is '.posix_getpid().', accept failed.'.PHP_EOL;
    return;
}
echo 'my pid is '.posix_getpid().', accept success.'.PHP_EOL;

開了4個子進程,然后用客戶端連接端口,發(fā)現(xiàn)每次驚群喚起的進程數(shù)量并不固定呢,這是為什么

my pid is 2388, accept failed.
my pid is 2390, accept failed.
my pid is 2389, accept failed.
my pid is 2387, accept success.

my pid is 2388, accept success.
my pid is 2390, accept failed.
my pid is 2387, accept failed.

my pid is 2390, accept success.
my pid is 2387, accept failed.
my pid is 2389, accept failed.
my pid is 2388, accept failed.

my pid is 2389, accept failed.
my pid is 2387, accept failed.
my pid is 2390, accept success.

my pid is 2390, accept success.
my pid is 2388, accept failed.

my pid is 2390, accept success.
my pid is 2387, accept failed.

my pid is 2390, accept success.
my pid is 2389, accept failed.
my pid is 2387, accept failed.

my pid is 2390, accept success.
my pid is 2388, accept failed.
  • dignfei 2020-03-13

    牛!?。。。。。。。。。。。。?!研究的這么深入!

walkor 打賞

是的,并不是每次都喚醒所有進程。
喚醒數(shù)一般和cpu核數(shù)以及各個進程繁忙程度有關(guān)。

1、如果進程都空閑,那么喚醒的進程數(shù)一般等于cpu核數(shù)
2、如果有些進程正在處理某些請求,這些進程就不會得到io復用(select/poll/epoll等)關(guān)于有新tcp鏈接的通知,那么喚醒的進程數(shù)一般小于cpu核數(shù)。

極端的情況的一個例子,如果只有一個進程空閑(阻塞在IO復用系統(tǒng)調(diào)用監(jiān)聽鏈接事件),那么只有它能立刻監(jiān)聽到有鏈接事件,它accept領(lǐng)走鏈接后,系統(tǒng)內(nèi)核鏈接隊列已經(jīng)是空了,等其它進程從繁忙轉(zhuǎn)到空閑時已經(jīng)沒有鏈接可以accept,所以其它進程不會再被通知有新鏈接而被喚醒。這種情況等于沒發(fā)生驚群效應。

我沒研究過linux源碼,上面都是一些經(jīng)驗之談,不一定十分準確。

  • 暫無評論
年代過于久遠,無法發(fā)表回答
??