日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > php >内容正文

php

PHP多进程之pcntl扩展的使用详解

發(fā)布時間:2024/9/20 php 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PHP多进程之pcntl扩展的使用详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

安裝

1.編譯php源碼時加入

--enable-pcntl

2.在現(xiàn)有的環(huán)境下新增加擴展

cd php-version/ext/pcntl phpize ./configure && make && make install echo "extension=pcntl.so" >> /etc/php.ini

3.Mac下用brew安裝 例如我本地是php7.1.5

brew install php71-pcntl

使用

header('content-type:text/html;charset=utf-8' ); // 必須加載擴展 if (!function_exists("pcntl_fork")) { die("pcntl extention is must !"); } pcntl_signal(SIGCHLD, SIG_IGN); //如果父進程不關(guān)心子進程什么時候結(jié)束,子進程結(jié)束后,內(nèi)核會回收。 $pid_dir = __dir__."/pid_files"; for($i=0; $i<3; $i++){$pid = pcntl_fork(); //創(chuàng)建子進程 if($pid == -1){//錯誤處理:創(chuàng)建子進程失敗時返回-1.var_dump("fork failed");}if(!$pid){//子進程得到的$pid為0, 所以這里是子進程執(zhí)行的邏輯。 //子進程代碼$pid = posix_getpid();$ppid = posix_getppid();$r = rand(0,100); //隨機數(shù)touch("$pid_dir/fork_child_process_{$i}_{$ppid}_{$pid}_{$r}");exit;}else{//父進程會得到子進程號,所以這里是父進程執(zhí)行的邏輯 //如果不需要阻塞進程,而又想得到子進程的退出狀態(tài),則可以注釋掉pcntl_wait($status)語句,或?qū)懗?#xff1a; pcntl_wait($status,WNOHANG); //等待子進程中斷,防止子進程成為僵尸進程。} } $pid = posix_getpid(); $ppid = posix_getppid(); $r = rand(0,100); //隨機數(shù) touch("$pid_dir/fork_process_pid_{$ppid}_{$pid}_$r");

相關(guān)參數(shù)

pcntl_waitpid

等待或返回fork的子進程狀態(tài)。
多進程的主進程創(chuàng)建了子進程,那主進程如何確認子進程的狀態(tài)呢。 假如主進程需要根據(jù)子進程的狀態(tài)做不同的處理呢, 這里的狀態(tài)包括子進程被kill掉,或變成僵尸進程等。 pcntl_waitpid就可以獲取子進程的狀態(tài)碼, 通過這個狀態(tài)碼, 就可知道子進程處于什么狀態(tài)
他的用法:

int pcntl_waitpid ( int $pid , int &$status [, int $options = 0 ] )

返回的值可以是-1,0或者 >0的值, 如果是-1, 表示子進程出錯, 如果>0表示子進程已經(jīng)退出且值是退出的子進程pid,至于如何退出, 可以通過$status狀態(tài)碼反應(yīng)。 那什么時候返回0呢, 只有在option 參數(shù)為 WNOHANG且子進程正在運行時0, 也就是說當(dāng)設(shè)置了options=WNOHANG時, 如果子進程還沒有退出, 此時pcntl_waitpid就會返回0
另外, 如果不設(shè)置這個參數(shù)為WNOHANG, pcntl_waitpid 就會阻塞運行, 直到子進程退出, 至于option的另外一個值WUNTRACED, 暫未理解, 不表

那么如何根據(jù)$status(狀態(tài)碼)判斷進程是如何退出呢, 如下(參數(shù)都是$status)

pcntl_wifexited

這個函數(shù)可以根據(jù)$status 判斷進程是否正常退出, 何為正常退出, 比如exit

pcntl_wexitstatus

這個函數(shù)僅在pcntl_wifexited 返回True(即正常退出)時有效, 且返回子進程退出的返回狀態(tài)碼, 這個返回狀態(tài)碼可以通過exit($s)的參數(shù)($s必須為整數(shù)時)定義

pcntl_wifsignaled

檢查子進程狀態(tài)碼是否代表由于某個信號而中斷, 比如是不是我們給他發(fā)送了term, int 等信號了

pcntl_wexitstatus

假如是發(fā)送信號而導(dǎo)致子進程中斷, 那么這個信號是什么信號呢, 這個函數(shù)就是獲取這個信號的

pcntl_wifstopped

僅當(dāng)option選項為WUNTRACED時有效, 未理解, 不表

pcntl_wtermsig

同上

綜合實例代碼:

$res = pcntl_waitpid($pid, $status, WNOHANG); //FileLog::log("pid is $pid; wait result is $res"); if($res == -1 || $res > 0){if(!pcntl_wifexited($status)){//進程非正常退出FileLog::log("service stop unusally; pid is $pid");}else{//獲取進程終端的退出狀態(tài)碼;$code = pcntl_wexitstatus($status);FileLog::log("service stop code: $code;pid is $pid ");}if(pcntl_wifsignaled($status)){//不是通過接受信號中斷FileLog::log("service stop not by signal;pid is $pid ");}else{$signal = pcntl_wtermsig($status);FileLog::log("service stop by signal $signal;pid is $pid");} }

上面的這個代碼就通過根據(jù)pcntl_waitpid的返回結(jié)果和狀態(tài)碼對子進程因為不同原因中斷做了不同的處理

來源:https://www.lvtao.net/dev/php-pcntl-process.html

總結(jié)

以上是生活随笔為你收集整理的PHP多进程之pcntl扩展的使用详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。