先查看下我安裝的PHP版本:
PHP 7.3.7 (cli) (built: Jul 12 2019 22:25:55) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.3.7, Copyright (c) 1998-2018 Zend Technologies
php實現多進程需要安裝pcntl模組,這個模組是php官方提供的,所以我們可以在PHP在原始碼中找到,下載php7.3.7 原始碼並解壓縮到 /home 目錄下,這時我們需要的擴充pcntl 在 /home/php-7.3.7/ext/pcntl
#依序執行以下指令:
phpize ./configure --with-php-config=/usr/local/bin/php-config make & make install
這裡面確定php-config
檔案的路徑可以使用 find / -name php-config
最後產生pcntl.so
檔案。
然後找到php的ini檔案所在路徑可以使用 php --ini
指令檢視
至於php的擴充模組路徑可以使用 php -i | grep extension_dir
查看,然後將產生的so檔案拷到模組路徑下並且將 extension=pcntl
加到php.ini檔案中
使用php -m 查看模組是否已載入!到這裡pcntl 模組就安裝好啦,下面開始編碼
for ($i = 0; $i < 3; $i++){ $pid = pcntl_fork(); if ($pid == -1) { die("开启进程失败"); } elseif ($pid) { echo "启动子进程 $pid \n"; } else { echo "子进程 ".getmypid()." 正在处理任务\n"; sleep(rand(5,10)); exit; } } while (pcntl_waitpid(0, $status) != -1) { $status = pcntl_wexitstatus($status); echo "子进程推出,状态码 $status \n"; }
pcntl_fork()
函數創建一個子進程,成功時,在父進程執行線程內返回產生的子進程的PID ,在子進程執行緒內回傳0。失敗時,在 父進程上下文傳回-1,不會建立子進程,並且會引發一個PHP錯誤。
pcntl_waitpid()
— 等待或返回fork的子進程狀態,掛起目前進程的執行直到參數pid指定的進程號的進程退出, 或接收到一個訊號要求中斷當前進程或呼叫一個訊號處理函數。傳回的值可以是-1,0或>0的值, 如果是-1, 表示子程序出錯, 如果>0表示子程序已經退出且值是退出的子程序pid,至於如何退出, 可以通過$status狀態碼反應
root@4226aaf8d937:/home/demo# php index.php 启动子进程 150 启动子进程 151 启动子进程 152 子进程 152 正在处理任务 子进程 151 正在处理任务 子进程 150 正在处理任务 子进程推出,状态码 0 子进程推出,状态码 0 子进程推出,状态码 0
root@4226aaf8d937:/# ps -aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.3 3976 3180 pts/0 Ss 04:42 0:00 bash root 17 0.0 0.3 3868 3184 pts/1 Ss 04:48 0:00 bash root 149 0.3 2.1 79740 21888 pts/0 S+ 06:18 0:00 php index.php root 150 0.0 0.6 79740 6664 pts/0 S+ 06:18 0:00 php index.php root 151 0.0 0.6 79740 6604 pts/0 S+ 06:18 0:00 php index.php root 152 0.0 0.6 79740 6604 pts/0 S+ 06:18 0:00 php index.php root 153 0.0 0.2 7640 2660 pts/1 R+ 06:18 0:00 ps -aux
當子程序被使用kill -9 行程id 強制殺死的時候如何處理?
<?php $pid_arr = []; for ($i = 0; $i < 3; $i++){ $pid = pcntl_fork(); if ($pid == -1) { die("开启进程失败"); } elseif ($pid) { echo "启动子进程 $pid \n"; array_push($pid_arr, $pid); } else { echo "子进程 ".getmypid()." 正在处理任务\n"; sleep(rand(5,10)); exit; } } for ($i=0; $i < count($pid_arr); $i++) { while (pcntl_waitpid($pid_arr[$i], $status) != -1) { if(!pcntl_wifexited($status)){ //进程非正常退出 if(pcntl_wifsignaled($status)){ $signal = pcntl_wtermsig($status); //不是通过接受信号中断 echo "子进程 $pid_arr[$i] 属于非正常停止,接收到信号 $signal \n"; }else{ print_r("子进程 $pid_arr[$i] 完成任务并退出 \n"); } }else{ //获取进程终端的退出状态码; $code = pcntl_wexitstatus($status); print_r("子进程 $pid_arr[$i] 正常结束任务并退出,状态码 $status \n "); } } }
pcntl_wifexited— 檢查狀態碼是否代表一個正常的退出
pcntl_wifsignaled — 檢查子行程狀態碼是否代表由於某個訊號而中斷
pcntl_wtermsig — 傳回導致子程序中斷的訊號
我們開啟兩個視窗其中之一:
想了解更多相關內容請造訪PHP中文網:PHP影片教學
#以上是PHP如何開啟pcntl模組並實現多進程程式設計?的詳細內容。更多資訊請關注PHP中文網其他相關文章!