PHP多程序任務學習實踐

2021-10-01 16:37:32 字數 3752 閱讀 5952

直接上**

ini_set

('display_errors'

,'off');

error_reporting

(e_all

^e_warning

^e_notice);

// 作用是每執行一次低階語句會檢查一次該程序是否有未處理過的訊號,ticks控制語句執行的條數

declare

(ticks =1)

;class

jobdaemondemo

public

function

run()}

}/**

* **執行邏輯:

* $pid = pcntl_fork() 方法會fork出乙個子程序,返回pid,然後**繼續順序執行

* $pid = -1,表示fork程序失敗

* $pid > 0,表示fork程序成功,返回子程序的pid,這一段可以執行主程序的業務邏輯

* $pid = 0,表示這段**是在子程序中執行的,這一段可以執行子程序的業務邏輯

** @param $job

* @return bool

*/protected

function

launchjob

($job

)elseif

($pid

===0

)else

to current jobs: $ \n"

;$this

->

currentjobs

[$pid]=

$job;}

}public

function

sighandler

($signo

,$pid

=null

,$status

=null

)elseif

(pcntl_wifexited

($status))

echo

"pid inner while: $pid

, status: $status

\n";if

(isset

($this

->

currentjobs

[$pid])

)echo

"-----------------------\n";}

}}(new

jobdaemondemo()

)->

run(

);

在測試多程序任務的時候,ps -ef 檢視程序,發現了如下輸出:

root@4efff09cfb9e:/# ps -ef

uid pid ppid c stime tty time cmd

root 1 0 0 dec12 ? 00:00:00 php -a

root 6 0 0 dec12 ? 00:00:00 /bin/bash

root 4878 0 11 dec16 ? 02:12:47 redis-server *:6379

root 5032 0 0 02:49 ? 00:00:00 /bin/bash

root 5052 0 0 02:50 ? 00:00:00 /bin/bash

root 5080 5032 60 03:13 ? 00:00:27 job-daemon

root 5082 5080 0 03:13 ? 00:00:00 [php] root 5083 5080 0 03:13 ? 00:00:00 [php] root 5084 5080 0 03:13 ? 00:00:00 [php] root 5085 5080 0 03:13 ? 00:00:00 [php] root 5087 5052 0 03:14 ? 00:00:00 ps -ef

[php]未知程序描述,查詢了下,這個是殭屍程序的描述資訊,於是就擴充套件學習了下什麼是殭屍程序。

什麼是defunct程序(殭屍程序)

在 linux 系統中,乙個程序結束了,但是他的父程序沒有等待(呼叫wait / waitpid)他,那麼他將變成乙個殭屍程序。當用ps命令觀察程序的執行狀態時,看到這些程序的狀態列為defunct。殭屍程序是乙個早已死亡的程序,但在程序表(processs table)中仍佔了乙個位置(slot)。

但是如果該程序的父程序已經先結束了,那麼該程序就不會變成殭屍程序。因為每個程序結束的時候,系統都會掃瞄當前系統中所執行的所有程序,看看有沒有哪個程序是剛剛結束的這個程序的子程序,如果是的話,就由init程序來接管他,成為他的父程序,從而保證每個程序都會有乙個父程序。而init程序會自動wait其子程序,因此被init接管的所有程序都不會變成殭屍程序。

linux下程序的運作方式

每個 linux程序在程序表裡都有乙個進入點(entry),核心程序執行該程序時使用到的一切資訊都儲存在進入點。當用 ps 命令察看系統中的程序資訊時,看到的就是程序表中的相關資料。當以fork()系統呼叫建立乙個新的程序後,核心程序就會在程序表中給這個新程序分配乙個進入點,然後將相關資訊儲存在該進入點所對應的程序表內。這些資訊中有一項是其父程序的識別碼。

子程序的結束和父程序的執行是乙個非同步過程,即父程序永遠無法**子程序到底什麼時候結束。那麼會不會因為父程序太忙來不及 wait 子程序,或者說不知道子程序什麼時候結束,而丟失子程序結束時的狀態資訊呢?

不會。因為 linux提供了一種機制可以保證,只要父程序想知道子程序結束時的狀態資訊,就可以得到。這種機制就是:當子程序走完了自己的生命週期後,它會執行exit()系統呼叫,核心釋放該程序所有的資源,包括開啟的檔案,占用的記憶體等。但是仍然為其保留一定的資訊(包括程序號the process id,退出碼exit code,退出狀態the terminationstatus of the process,執行時間the amount of cpu time taken by the process等),這些資料會一直保留到系統將它傳遞給它的父程序為止,直到父程序通過wait / waitpid來取時才釋放。

也就是說,當乙個程序死亡時,它並不是完全的消失了。程序終止,它不再執行,但是還有一些殘留的資料等待父程序收回。當父程序 fork() 乙個子程序後,它必須用 wait() (或者 waitpid())等待子程序退出。正是這個 wait() 動作來讓子程序的殘留資料消失。

殭屍程序的危害

如果父程序不呼叫wait / waitpid的話,那麼保留的那段資訊就不會釋放,其程序號就會一直被占用,但是系統的程序表容量是有限的,所能使用的程序號也是有限的,如果大量的產生殭屍程序,將因為沒有可用的程序號而導致系統不能產生新的程序。

所以,defunct程序不僅占用系統的記憶體資源,影響系統的效能,而且如果其數目太多,還會導致系統癱瘓。而且,由於排程程式無法選中defunct 程序,所以不能用kill命令刪除defunct 程序,惟一的方法只有重啟系統。

如何殺死defunct程序

defunct程序是指出錯損壞的程序,父子程序之間不會再通訊。有時,它們會演變成「殭屍程序」,存留在你的系統中,直到系統重啟。可以嘗試 「kill -9」 命令來清除,但多數時候不管用。

為了殺死這些defunct程序,你有兩個選擇:

1、重啟你的計算機

2、kill掉父程序

PHP多程序處理任務

系統 linux php 4 4.1.0,php 5,php 7 擴充套件 pcntlposixphp 多程序一般應用在 php cli 命令列中執行 php 指令碼,不要在 web 訪問時使用。多程序處理分解任務一般要比單程序更快。php 檢視是否安裝多程序模組 pcntl 是 process c...

PHP 多程序處理任務

乙個 php 多程序簡單例子大概是這個樣子 5 個子程序處理任務 for i 0 i 5 i elseif pid else 等待子程序執行結束 while pcntl waitpid 0 status 1 當然實際應用中我們不能夠這樣輸出 不夠健壯,也不夠優雅,我所以找了個基於pcntl封裝的擴充...

php利用多程序處理任務

注 php多程序一般應用在php cli命令列中執行php指令碼,做程序任務時要檢查php是否開啟了pcntl擴充套件,pcntl是process control程序管理的縮寫 pcntl fork 在當前程序當前位置產生分支 子程序 乙個fork子程序的基礎示例 pid pcntl fork 父程...