
みなさんこんにちは!
Habrには、PHPでデーモンを作成する方法やその他の分岐したものに関する記事がたくさんありました。 同様の、しかしやや異なるトピックでの私の開発を共有したいと思います-
複数のPHPプロセスを管理します 。
まず、記事
で使用されている
用語の小さな
用語集 。
- ジョブは、別のプロセスで実行されるタスクです。 コンソールに「php test.php」と入力します-これが仕事です。
- Job ManagerまたはProcess Managerは、タスクを管理するプロセスです。 出力を収集して処理し、入力にメッセージを送信できます。
タスク
の目標は 、すでに実行中の作業プロセスに影響を与え、その実装の進捗に関する情報を取得できるようにすることです。
新しいプロセスを開始するには、
proc_open関数を使用します。これにより、新しいプロセスのI / O記述子を再定義できます。 単一のプロセスを管理するために、Jobクラスが開発されました。 作業は、名前と実行されたチームによって特徴付けられます。
class Job { protected $_pid = 0; protected $_name; protected $_cmd = ''; protected $_stderr = '/dev/null'; private $_resource = NULL; private $_pipes = array(); private $_waitpid = TRUE; public function __construct($cmd, $name = 'job') { $this->_cmd = $cmd; $this->_name = $name; } public function __destruct() {
ジョブを管理するために、Job_Managerクラスが作成されます。これは、基本的にスキーム全体のキーです。
class Job_Manager { private $_pool_size = 20; private $_pool = array(); private $_streams = array(); private $_stderr = array(); private $_is_terminated = FALSE; protected $_dispatch_function = NULL; public function __construct() {
いくつかの抽象タスクを管理する方法を既に学習しましたが、実行可能プロセス自体のクラスを実装することは残っています。
class Executable { protected $_is_terminated = FALSE; protected $_cleanup_function = NULL; public function __construct() {
プロセスマネージャの使用例として、「スリープ」プロセスを実装します。これは、STDOUTでスリープし、サブスクライブ解除するスクリプトです。
sleep.php class SleeperTest extends Executable { public function sleep() { for($i = 0; !$this->isTerminated() && $i < 10; $i++) { ob_start(); echo $i . "\n"; ob_end_flush(); sleep(5); } } } $s = new SleeperTest; $s->sleep();
pm.php $pm = new Job_Manager; $pm->startJob('php sleep.php', 'sleeper1'); $pm->startJob('php sleep.php', 'sleeper2');
実装で使用されるノンブロッキング記述子とstream_select関数を使用すると、あらゆる種類のデーモンに典型的な問題(アイドルサイクルでのCPU使用率が高くなる)を回避できます。 提案された方法にはこの欠点がなく、すべてがスムーズかつ穏やかに機能します。
更新 クラスソースをgithub
https://github.com/xzag/php-pmに投稿しました