多行程環境要求
- Linux 系統
- php-cli 模式
- pcntl 擴展 或 swoole 擴展
pcntl 擴展
<?php
$str = "hello world!" . PHP_EOL;
// 派生一個子行程,子行程會復制主行程中的背景關系
// pcntl_fork 函式在主行程中回傳子行程的行程ID,在子行程回傳0,失敗在主行程回傳-1
$pid = pcntl_fork();
// 這里開始的代碼,會被主行程、子行程共同執行
echo $str;
if($pid > 0) {
echo "我是主行程,子行程的pid是{$pid}" . PHP_EOL;
} elseif($pid == 0) {
echo "我是子行程,我的pid是". getmypid() . PHP_EOL;
}else{
echo "我是主行程,開啟子行程失敗" . PHP_EOL;
}
swoole 擴展
<?php
use Swoole\Process;
$str = "hello world!" . PHP_EOL;
// 實體化一個行程類
$process = new Process(function() use($str) {
echo $str;
echo "我是子行程,我的pid是" . getmypid() . PHP_EOL;
});
// 開啟子行程,成功回傳子行程的PID,失敗回傳false
$pid = $process->start();
echo $str;
if($pid > 0){
$status = Process::wait(true);
echo "我是主行程,子行程的pid是{$pid}" . PHP_EOL;
}else{
echo "我是主行程,開啟子行程失敗" . PHP_EOL;
}
行程通信
通常情況下,各個行程之間的記憶體空間是相互獨立的,不能互相訪問,
在PHP多行程中,pcntl_fork出來的子行程只是復制了父行程的背景關系內容,并非共享同一個記憶體空間,多行程之間無法直接通信,
行程間通信的幾種方式:
- 管道通信:分為有名管道,無名管道等;
- 訊息佇列通信:使用linux的訊息佇列,需要借助sysvmsg擴展;
- 行程信號通信;
- 共享記憶體通信:映射一段能被其他行程訪問的記憶體,這段共享記憶體由一個行程創建,但多個行程都可以訪問;
- 套接字通信;
- 第三方通信:使用檔案、mysql、redis等方法實作通信,
行程信號
行程信號(Signals)是Unix系統中使用的最古老的行程間通信方法之一,作業系統通過信號來通知行程系統中發生了某種預先規定好的事件,它也是用戶行程之間通信和同步的一種原始機制,一個鍵盤中斷或者一個錯誤條件都有可能產生一個信號,Shell也使用信號向它的子行程發送作業控制信號,
在一個信號的生命周期中有兩個階段:生成和傳送,
當一個事件發生時,需要通知一個行程,這時就生成了一個信號,
當行程識別出信號的到來,會采取適當的動作來傳送或處理信號,
在信號到來和行程對信號進行處理之間,信號在行程上掛起(pending),
主要的信號源如下:
- 例外:行程運行程序中出現例外;
- 其它行程:一個行程可以向另一個或一組行程發送信號;
- 終端中斷:Ctrl-C,Ctrl-\等;
- 作業控制:前臺、后臺行程的管理;
- 分配額:CPU超時或檔案大小突破限制;
- 通知:通知行程某事件發生,如I/O就緒等;
- 報警:計時器到期,
常見信號
- SIGHUP: 從終端上發出的結束信號;
- SIGINT: 來自鍵盤的中斷信號(Ctrl-C);
- SIGQUIT:來自鍵盤的退出信號(Ctrl-\);
- SIGFPE: 浮點例外信號(例如浮點運算溢位);
- SIGKILL:結束接收此信號的行程;
- SIGALRM:行程的定時器到期時,發送該信號;
- SIGTERM:kill 命令發出的信號;
- SIGCHLD:標識子行程停止運行或已運行結束的信號;
信號預設動作
- 例外終止(abort):在行程的當前目錄下,把行程的地址空間內容、暫存器內容保存到一個叫做core的檔案中,然后終止行程,
- 退出(exit):不產生core檔案,直接終止行程,
- 忽略(ignore):忽略該信號,
- 停止(stop):掛起該行程,
- 繼續(continue):如果行程被掛起,則恢復行程的運行,否則,忽略信號,
行程可以對信號所采取的操作
- 忽略信號:行程可忽略產生的信號,但 SIGKILL 和 SIGSTOP 信號不能被忽略,必須處理(由行程自己或由內核處理),行程可以忽略掉系統產生的大多數信號,
- 阻塞信號:行程可選擇阻塞某些信號,即先將到來的某些信號記錄下來,等到以后(解除阻塞后)再處理它,
- 由行程處理該信號:行程本身可在系統中注冊處理信號的處理程式地址,當發出該信號時,由注冊的處理程式處理信號,
- 由內核進行預設處理:信號由內核的預設處理程式處理,執行該信號的預設動作,例如,行程接收到SIGFPE(浮點例外)的預設動作是產生core并退出,大多數情況下,信號由內核處理,
信號沒有固有的優先級,如果為一個行程同時產生了兩個信號,這兩個信號會以任意順序出現在行程中并會按任意順序被處理,另外,也沒有機制用于區分同一種類的多個信號,如果行程在處理某個信號之前,又有相同的信號發出,則行程只能接收到一個信號,行程無法知道它接收了一個還是多個SIGCONT信號,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/36353.html
標籤:PHP
上一篇:Flyway版本化管理資料庫腳本
