php pcntl_fork 多程序殭屍程序的問題
因業務需要用到了pcntl_fork 處理多客戶端連線處理資料的需求
但測試下來出現一個問題:
fork 之後, 若等待子程序返回, 那麼程式就會阻塞, 不等待子程序返回, 則會出現殭屍程序
$obj = new service('127.0.0.1', 50000); $obj->run(); class service { private $socket_id; private $socket_cid; private $pid; function __construct($host, $port) { $this->socket_id = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if (!$this->socket_id) { $this->logs("create socket error"); return false; } if (!socket_bind($this->socket_id, $host, $port)) { $this->logs(socket_strerror(socket_last_error())); socket_close($this->socket_id); return false; } if (!socket_listen($this->socket_id)) { $this->logs(socket_strerror(socket_last_error())); socket_close($this->socket_id); return false; } } public function run() { if (!$this->socket_id) { $this->logs("create socket error"); return false; } $this->logs("Starting..."); while (true) { $this->socket_cid = socket_accept($this->socket_id); $ip = ""; socket_getpeername($this->socket_cid, $ip); $this->logs("Client IP: {$ip}"); if (!is_resource($this->socket_cid)) { $this->logs(socket_strerror(socket_last_error())); socket_close($this->socket_id); return false; } $this->pid = pcntl_fork(); if ($this->pid == -1) { $this->logs(socket_strerror(socket_last_error())); socket_close($this->socket_cid); return false; } else if ($this->pid) { $status = 0; $s = pcntl_wait($status, WNOHANG); //等待子程序中斷,防止子程序成為殭屍程序, 但這樣會阻塞, 意思是隻能處理一個客戶端連線, 多個進入排隊 //$s = pcntl_waitpid(0, $status, WUNTRACED); //如果不等待, 則子程序處理完之後, 沒有對其進行處理, 會成為殭屍程序 $this->logs("Status: " . $status . ", pcntl_waitpid: " . $s); } elseif ($this->pid == 0) { //child process $k = 0; while (true) { if ($data = socket_read($this->socket_cid, 1024)) { $this->logs("Read Data: {$data}"); $flag = socket_write($this->socket_cid, date('Y-m-d H:i:s') . '|已收到'); $this->logs("Write Result: {$flag}"); } sleep(1); $k++; $this->logs("Wait...\t" . date('Y-m-d H:i:s')); if ($k > 30) { break; } } socket_close($this->socket_cid); exit(1); } } socket_close($this->socket_id); } /** * 打日誌 * @param string $msg * @return int */ private function logs($msg) { $logs_filename = LOGS_PATH; if (!file_exists($logs_filename)) { @mkdir($logs_filename, 0777, true); } $logs_filename .= date('j') . '.log'; $logs_data = date('[H:i:s]') . " {$msg}\n"; return file_put_contents($logs_filename, $logs_data, FILE_APPEND); } function __destruct() { if (is_resource($this->socket_id)) { socket_close($this->socket_id); } if (is_resource($this->socket_cid)) { socket_close($this->socket_cid); } } }
在網上搜了半天, 這位仁兄的解決辦法是對的(http://blog.csdn.net/e421083458/article/details/22186475), 就是增加訊號處理,
在socket accept之前加上 pcntl_signal(SIGCHLD, SIG_IGN); //如果父程序不關心子程序什麼時候結束,子程序結束後,核心會回收。
也就是在run方法開始處 :)
public function run() { if (!$this->socket_id) { $this->logs("create socket error"); return false; } pcntl_signal(SIGCHLD, SIG_IGN); $this->logs("Starting...."); ... }
相關推薦
php pcntl_fork 多程序殭屍程序的問題
因業務需要用到了pcntl_fork 處理多客戶端連線處理資料的需求 但測試下來出現一個問題: fork 之後, 若等待子程序返回, 那麼程式就會阻塞, 不等待子程序返回, 則會出現殭屍程序 $obj = new service('127.0.0.1', 50000);
Kill殺死Linux中的defunct程序(殭屍程序)
一、什麼是defunct程序(殭屍程序)? 在 Linux 系統中,一個程序結束了,但是他的父程序沒有等待(呼叫wait / waitpid)他,那麼他將變成一個殭屍程序。當用ps命令觀察程序的執行狀態時,看到這些程序的狀態列為defunct。殭屍程序是一個早已
Linux 多工程式設計——特殊程序:殭屍程序、孤兒程序、守護程序
殭屍程序(Zombie Process) 程序已執行結束,但程序的佔用的資源未被回收,這樣的程序稱為殭屍程序。 在每個程序退出的時候,核心釋放該程序所有的資源、包括開啟的檔案、佔用的記憶體等。 但是仍然為其保留一定的資訊,這些資訊主要主要指程序控制塊的資訊(包括程序號、退出狀態、執行時
PHP利用多程序處理任務(一篇寫得比較容易理解的多程序文章)
PHP多程序一般應用在PHP_CLI命令列中執行php指令碼,不要在web訪問時使用。 多程序處理分解任務一般要比單程序更快。 php檢視是否安裝多程序模組: php -m
使用Phalcon+PHP-FPM構建PHP基於多程序的資料庫連線池
之前看到網上有一篇文章說Phalcon和PHP沒有資料庫連線池,而swoole本身提供了很好的資料庫連線池。實際上這是一種誤解,PHP自身早就實現了持久化的資料庫連線。而Phalcon基於zephir寫的資料庫連線介面卡,必然也是支援PHP自身實現的這種資料
多程序併發如何防止殭屍程序——伺服器開發
在併發伺服器設計中,很常用的一種辦法是用fork為每個連線建立子程序來單獨處理客戶端請求。 流程圖如下: 可見,在父程序中直接執行accept等待下一個連線而並沒有用wait或者waitpid來等待子程序返回。這會造成怎樣的後果呢?當子程序exit退出的時候,它並沒有真正
【C/C++】多程序:殭屍程序
一個殭屍程序產生的過程是:父程序呼叫fork建立子程序後,子程序執行至其終止。程序終止後有些資訊對於父程序和核心還是很有用的,例如程序的ID號、程序的退出狀態、程序執行的CPU時間等。因此程序執行終止後,系統會回收所有核心分配給它的記憶體、關閉它所開啟的檔案等,但是還會保
以例項全面講解PHP中多程序程式設計的相關函式的使用,php函式
PHP有一組程序控制函式(編譯時需要–enable-pcntl與posix擴充套件),使得php能實現跟c一樣的建立子程序、使用exec函式執行程式、處理訊號等功能。 <?php header('content-type:text/html;char
PHP實現多程序並行執行指令碼
由於php的程序是不支援多執行緒的,有些場景為了方便以及提高效能,可以用php實現多程序以彌補這個不足: #!/usr/bin/env php < ?php $cmds=array(
php+Socket多程序處理速學:防止子程序無限增加
<?php $socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP); socket_bind($socket,'127.0.0.1',9090) or die('error'); socket_listen($socket,5); $child =
php swoole 多程序傳送微信模板訊息\郵件
年前接到需求做了一個功能,給快到期的微信使用者傳送模板訊息,提醒續費. 首先拿到快到期的使用者, 每天大概800-2000不等,感覺壓力不是很大,直接foreach 陣列 然後傳送,經常出現請求超時 也就是502的問題,緊接著運營同事提出要針對一大批使用者 推模板
PHP解決多程序同時讀寫一個…
/* *flock(file,lock,block) *file 必需,規定要鎖定或釋放的已開啟的檔案 *lock 必需。規定要使用哪種鎖定型別。 *block 可選。若設定為 1 或 true,則當進行鎖定時阻擋其他程序。 *lock *LOCK_SH 要取得共享鎖定(讀取的程式) *LOCK_EX 要取
gdb調試多進程多線程程序
mage 支持 nbsp rgs 提示 功能 網絡 網絡編程 指令 一、調試的指令 1.list命令 list linenum 顯示程序第linenum行的周圍的程序 list function 顯示程序名為function的函數的源程序
【2017-06-20】Linux應用開發工程師C/C++面試問題之一:Linux多線程程序的同步問題
依次 其它 如果 開發工程師 logs 特殊 另一個 特殊情況 發生 參考之一:Linux 線程同步的三種方法 鏈接地址:http://www.cnblogs.com/eleclsc/p/5838790.html 簡要回答: Linux下線程同步最常用的三種方法就是互斥鎖、
php異步執行其他程序
user ajax linux pen ignore curl 設置 缺失 開啟 這裏的“其他程序”,可能是linux命令,可能是其他的php文件。 網上說法有四種。分別為: 1、通過加載頁面的時候通過ajax技術異步請求服務器 2、通過popen()函數 3、通過curl
如何同時打開多個應用程序
需要 復制 strong 多個 允許 tro start 並保存 技術分享 每天早上打開電腦後都需要打開多個應用程序,一個一個的打開很麻煩,下面的操作將實現如何同時打開多個應用程序: 1.首先,新建一個txt文件 2.右鍵單擊要打開的應用程序,並點擊屬性,在彈出框中復制目標
CountDownLatch在多線程程序中的應用
exception pac 所有 args lar hash oid sys exc 一.CountDownLatch介紹 CountDownLatch是JDK1.5之後引入的,存在於java.util.concurrent包下,能夠使一個線程等待其他線程完成動作後再執行。
ThreadLocal 解決多線程程序的並發問題+事務處理
{} cep 程序管理 sta cte read nag lease 管理 1 import java.sql.Connection; 2 import java.sql.SQLException; 3 4 public class TranManager
gdb調試多線程程序總結
done sysv php inux 提示信息 pst works his argc gdb調試多線程程序總結 來源 https://www.cnblogs.com/jingzhishen/p/4324071.html 一、多線程調試1. 多線程調試,最重要的幾個命令
使用 GDB 調試多進程程序
tin 出現 二進制 nom 主題 rtu 錯誤 virtual pad 使用 GDB 調試多進程程序 來源 https://www.ibm.com/developerworks/cn/linux/l-cn-gdbmp/index.html GDB 是 linux 系統