成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

PHP多進程系列筆記(二)

CatalpaFlat / 3073人閱讀

摘要:任何進程在退出前使用退出都會變成僵尸進程用于保存進程的狀態(tài)等信息,然后由進程接管。這時候就算手動結(jié)束腳本程序也無法關(guān)閉這個僵尸子進程了。那么子進程結(jié)束后,沒有回收,就產(chǎn)生僵尸進程了。本小節(jié)我們通過安裝信號處理函數(shù)來解決僵尸進程問題。

上一篇文章講解了pcntl_forkpcntl_wait兩個函數(shù)的使用,本篇繼續(xù)講解PHP多進程相關(guān)新知識。

僵尸(zombie)進程

這里說下僵尸進程:

僵尸進程是指的父進程已經(jīng)退出,而該進程dead之后沒有進程接受,就成為僵尸進程(zombie)進程。任何進程在退出前(使用exit退出) 都會變成僵尸進程(用于保存進程的狀態(tài)等信息),然后由init進程接管。如果不及時回收僵尸進程,那么它在系統(tǒng)中就會占用一個進程表項,如果這種僵尸進程過多,最后系統(tǒng)就沒有可以用的進程表項,于是也無法再運行其它的程序。

通過如下命令查看是否有僵尸進程,如果有,類似下面這樣:

$ ps -A -o stat,ppid,pid,cmd | grep -e "^[Zz]"
Z+     282   283 [php] 

如果子進程還沒有結(jié)束時,父進程就結(jié)束了,那么init進程會自動接手這個子進程,進行回收。

如果父進程是循環(huán),又沒有安裝SIGCHLD信號處理函數(shù)調(diào)用waitwaitpid()等待子進程結(jié)束。那么子進程結(jié)束后,沒有回收,就產(chǎn)生僵尸進程了。

示例:
fork_zombie.php


命令行里運行程序,然后新終端查看:

$ ps -A -o stat,ppid,pid,cmd | grep -e "^[Zz]"
Z+    7252  7253 [php] 

出現(xiàn)了一個僵尸進程。這時候就算手動結(jié)束腳本程序也無法關(guān)閉這個僵尸子進程了。需要使用kill -9關(guān)閉。

pcntl_signal
bool pcntl_signal ( int $signo , callback $handler [, bool $restart_syscalls = true ] )

該函數(shù)為signo指定的信號安裝一個新的信號處理器。

安裝SIGCHLD信號

上一節(jié)里,我們講到僵尸進程產(chǎn)生的原因:

如果父進程是循環(huán),又沒有安裝SIGCHLD信號處理函數(shù)調(diào)用waitwaitpid()等待子進程結(jié)束。那么子進程結(jié)束后,沒有回收,就產(chǎn)生僵尸進程了。

本小節(jié)我們通過安裝SIGCHLD信號處理函數(shù)來解決僵尸進程問題。示例:


第一次注釋掉#1#2處的代碼,父進程提前結(jié)束,子進程被init進程接手,所以沒有產(chǎn)生僵尸進程。
第二次我們注釋掉#2處的代碼,開啟#1處的代碼,即父進程是個死循環(huán),又沒有回收子進程,就產(chǎn)生僵尸進程了。
第三次我們開啟#1處和#2處的代碼,父進程由于安裝了信號處理,并調(diào)用wait函數(shù)等待子進程結(jié)束,所以也沒有產(chǎn)生僵尸進程。

對子進程的結(jié)束不感興趣
如果父進程不關(guān)心子進程什么時候結(jié)束,那么可以用pcntl_signal(SIGCHLD, SIG_IGN)通知內(nèi)核,自己對子進程的結(jié)束不感興趣,那么子進程結(jié)束后,內(nèi)核會回收,并不再給父進程發(fā)送信號。這樣我們就不寫子進程退出的處理函數(shù)了。

說明:

如果去掉declare( ticks  =  1 );無法響應(yīng)信號。因php的信號處理函數(shù)是基于ticks來實現(xiàn)的,而不是注冊到真正系統(tǒng)底層的信號處理函數(shù)中。
安裝其他信號

我們可以在主進程安裝更多信號,例如:


注:通過 kill -l 可以看到Linux下所有的信號常量。
$ kill -l
 1) SIGHUP     2) SIGINT     3) SIGQUIT     4) SIGILL     5) SIGTRAP
 6) SIGABRT     7) SIGBUS     8) SIGFPE     9) SIGKILL    10) SIGUSR1
11) SIGSEGV    12) SIGUSR2    13) SIGPIPE    14) SIGALRM    15) SIGTERM
16) SIGSTKFLT    17) SIGCHLD    18) SIGCONT    19) SIGSTOP    20) SIGTSTP
21) SIGTTIN    22) SIGTTOU    23) SIGURG    24) SIGXCPU    25) SIGXFSZ
26) SIGVTALRM    27) SIGPROF    28) SIGWINCH    29) SIGIO    30) SIGPWR
31) SIGSYS    34) SIGRTMIN    35) SIGRTMIN+1    36) SIGRTMIN+2    37) SIGRTMIN+3
38) SIGRTMIN+4    39) SIGRTMIN+5    40) SIGRTMIN+6    41) SIGRTMIN+7    42) SIGRTMIN+8
43) SIGRTMIN+9    44) SIGRTMIN+10    45) SIGRTMIN+11    46) SIGRTMIN+12    47) SIGRTMIN+13
48) SIGRTMIN+14    49) SIGRTMIN+15    50) SIGRTMAX-14    51) SIGRTMAX-13    52) SIGRTMAX-12
53) SIGRTMAX-11    54) SIGRTMAX-10    55) SIGRTMAX-9    56) SIGRTMAX-8    57) SIGRTMAX-7
58) SIGRTMAX-6    59) SIGRTMAX-5    60) SIGRTMAX-4    61) SIGRTMAX-3    62) SIGRTMAX-2
63) SIGRTMAX-1    64) SIGRTMAX    

防盜版聲明:本文系原創(chuàng)文章,發(fā)布于公眾號飛鴻影的博客(fhyblog)及博客園,轉(zhuǎn)載需作者同意。


ticks相關(guān)
PHP的 ticks=1 表示每執(zhí)行1行PHP代碼就回調(diào)此函數(shù)(指的pcntl_signal_dispatch)。實際上大部分時間都沒有信號產(chǎn)生,但ticks的函數(shù)一直會執(zhí)行。如果一個服務(wù)器程序1秒中接收1000次請求,平均每個請求要執(zhí)行1000行PHP代碼。那么PHP的pcntl_signal,就帶來了額外的 1000 * 1000,也就是100萬次空的函數(shù)調(diào)用。這樣會浪費大量的CPU資源。
(摘自:韓天峰(Rango)的博客 ? PHP官方的pcntl_signal性能極差
http://rango.swoole.com/archi...

pcntl_signal_dispatch的作用就是查看是否收到了信號需要處理,如果有信號的話,就調(diào)用相應(yīng)的信號處理函數(shù)。

所以上述問題比較好的做法是去掉ticks,轉(zhuǎn)而手動調(diào)用pcntl_signal_dispatch,在代碼循環(huán)中自行處理信號。

我們把上一小節(jié)的例子改改,不使用ticks:


運行結(jié)果:

Installing signal handler...
Generating signal SIGTERM to self...
Caught SIGUSR1...
Done

相比每執(zhí)行一條php語句都會調(diào)用 pcntl_signal_dispatch 一次,效率好多了。

pcntl_alarm
int pcntl_alarm ( int $seconds )

該函數(shù)創(chuàng)建一個計時器,在指定的秒數(shù)后向進程發(fā)送一個 SIGALRM 信號。每次對 pcntl_alarm() 的調(diào)用都會取消之前設(shè)置的alarm信號。注意不是定時器,只會運行一次。

下面是一個隔5秒發(fā)送一個SIGALRM信號,并由signal_handler函數(shù)獲取,然后打印一個 SIGALRM 的例子:


注:如果不想使用ticks,那么需要在主循環(huán)里主動增加pcntl_signal_dispatch()調(diào)用。

(未完待續(xù))


歡迎關(guān)注公眾號及時獲取最新文章推送!


推薦!每月僅需$2.5,即可擁有配置SSD的VPS!

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/28866.html

相關(guān)文章

  • PHP進程系列筆記(一)

    摘要:用于創(chuàng)建子進程。該函數(shù)阻塞當(dāng)前進程,只到當(dāng)前進程的一個子進程退出或者收到一個結(jié)束當(dāng)前進程的信號。注意處需要注意子進程需要防止子進程也進入循環(huán)。如果沒有,最終創(chuàng)建的子進程不只個。 本系列文章將向大家講解pcntl_*系列函數(shù),從而更深入的理解進程相關(guān)知識。 PCNTL在PHP中進程控制支持默認是關(guān)閉的。您需要使用 --enable-pcntl 配置選項重新編譯PHP的 CGI或CLI版本...

    ddongjian0000 評論0 收藏0
  • PHP進程系列筆記(五)

    摘要:消息隊列更常見的用途是主進程分配任務(wù),子進程消費執(zhí)行。子進程前面加了個,這是為了防止父進程還未往消息隊列中加入內(nèi)容直接退出。 前面幾節(jié)都是講解pcntl擴展實現(xiàn)的多進程程序。本節(jié)給大家介紹swoole擴展的swoole_process模塊。 swoole多進程 swoole_process 是swoole提供的進程管理模塊,用來替代PHP的pcntl擴展。 首先,確保安裝的swoole...

    qianfeng 評論0 收藏0
  • PHP進程系列筆記(四)

    摘要:本節(jié)主要講解常用函數(shù)和進程池的概念,也會涉及到守護進程的知識。所以任何時候,建議預(yù)先創(chuàng)建好進程,也就是使用進程池的方式實現(xiàn)。 本節(jié)主要講解Posix常用函數(shù)和進程池的概念,也會涉及到守護進程的知識。本節(jié)難度較低。 Posix常用函數(shù) posix_kill 向指定pid進程發(fā)送信號。成功時返回 TRUE , 或者在失敗時返回 FALSE 。 bool posix_kill ( int $...

    Cc_2011 評論0 收藏0
  • PHP 進程系列筆記(三)

    摘要:本節(jié)講解幾個多進程的實例。新開終端,我們使用命令查看進程可以看到個進程個主進程,個子進程。使用命令結(jié)束子進程,主進程會重新拉起一個新的子進程。 本節(jié)講解幾個多進程的實例。 多進程實例 Master-Worker結(jié)構(gòu) 下面例子實現(xiàn)了簡單的多進程管理: 支持設(shè)置最大子進程數(shù) Master-Worker結(jié)構(gòu):Worker掛掉,Master進程會重新創(chuàng)建一個

    focusj 評論0 收藏0
  • php進程插入數(shù)據(jù)(pcntl 學(xué)習(xí)筆記)

    摘要:進程切換太多,影響了了效率應(yīng)該是原因之一。當(dāng)時,十萬條記錄,個進程插入總時間為單進程插入萬條數(shù)據(jù),耗時秒,相對個進程插入萬記錄來說,耗時少些。而單進程插入萬條記錄,耗時,相對來說,是挺慢的了。 個人在虛擬機centos7,單核,1G內(nèi)存 /** * 模擬并發(fā)請求,10萬次寫入數(shù)據(jù)庫 * 拆分為10個進程,每個進程處理一萬條插入 */ $total = 10000; $num ...

    CoyPan 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<