function master_process($workers) { //监听子进程,如果停止,会再拉起来 swoole_process::signal(SIGCHLD, function ($signo) use(&$workers) { while (1) { $ret = swoole_process::wait(false); if ($ret) { $pid = $ret['pid']; //这里实现一个自动拉起的能力 $child_process = $workers[$pid]; logprint('info', "Worker Exit, kill_signal={$ret['signal']} PID=" . $pid); $new_pid = $child_process->start(); $workers[$new_pid] = $child_process; unset($workers[$pid]); } else { break; } } }); //kill -10 结束全部程序 swoole_process::signal(SIGUSR1, function ($signo) use(&$workers) { swoole_process::signal(SIGCHLD, null); foreach ($workers as $pid => $worker) { swoole_process::kill($pid); } //处理子进程,然后自己退出 exit; }); }
/** * 注册信号 */ public static function registerSignal() { //终止进程 \swoole_process::signal(SIGTERM, function ($signo) { self::exit2p('master process [' . self::$process_name . '] exit'); }); //忽略信号,当子进程停止或退出时通知父进程 \swoole_process::signal(SIGCHLD, function ($signo) { //非阻塞等待 while ($ret = \swoole_process::wait(false)) { $pid = $ret['pid']; if (isset(self::$worker_list[$pid])) { $worker = self::$worker_list[$pid]; $worker['process']->close(); //重启该子进程 self::createWorkerProcess($worker['className'], $worker['number'], $worker['options']); defined('PHPKIT_RUN_DEBUG') && syslog(LOG_INFO, 'child process restart:' . $pid); } } }); //终止进程,用户定义信号1 \swoole_process::signal(SIGUSR1, function ($signo) { //TODO something }); defined('PHPKIT_RUN_DEBUG') && syslog(LOG_INFO, 'register signal success'); }
/** * 注册信号 */ public static function registerSignal() { //终止进程 \swoole_process::signal(SIGTERM, function ($signo) { self::exit2p('master process [' . self::$process_name . '] exit'); }); //忽略信号,当子进程停止或退出时通知父进程 \swoole_process::signal(SIGCHLD, function ($signo) { //非阻塞等待 while ($ret = \swoole_process::wait(false)) { $pid = $ret['pid']; if (isset(self::$worker_list[$pid])) { $task = self::$worker_list[$pid]; $id = $task['id']; $task['process']->close(); unset(self::$worker_list[$pid]); if (isset(self::$unique_task_list[$id]) && self::$unique_task_list[$id] > 0) { self::$unique_task_list[$id]--; } defined('PHPKIT_RUN_DEBUG') && syslog(LOG_INFO, 'child process exit:' . $pid); } } }); //终止进程,用户定义信号1 \swoole_process::signal(SIGUSR1, function ($signo) { //TODO something }); defined('PHPKIT_RUN_DEBUG') && syslog(LOG_INFO, 'register signal success'); }
function run($options) { $asDaemon = isset($options['asDaemon']) ? $options['asDaemon'] : 0; if ($asDaemon) { \swoole_process::daemon(); } $pids = []; $workers = []; for ($i = 0; $i < $this->worker_num; $i++) { $process = new \swoole_process($this->workerStart, $this->redirect_stdout); $process->id = $i; $pid = $process->start(); $pids[] = $pid; $workers[$pid] = $process; } $pidFile = isset($options['pidFile']) ? $options['pidFile'] : 0; if ($pidFile) { $ppid = posix_getpid(); $pids[] = $ppid; file_put_contents($pidFile, implode("|", $pids)); } \swoole_process::signal(SIGTERM, function () use($workers) { exit(0); }); \swoole_process::signal(SIGINT, function () { exit(0); }); \swoole_process::wait(false); return $workers; }
function master_async($workers) { swoole_process::signal(SIGCHLD, function ($signo) use(&$workers) { while (1) { $ret = swoole_process::wait(false); if ($ret) { $pid = $ret['pid']; $child_process = $workers[$pid]; //unset($workers[$pid]); echo "Worker Exit, kill_signal={$ret['signal']} PID=" . $pid . PHP_EOL; $new_pid = $child_process->start(); $workers[$new_pid] = $child_process; unset($workers[$pid]); } else { break; } } }); /** * @var $process swoole_process */ foreach ($workers as $pid => $process) { swoole_event_add($process->pipe, function ($pipe) use($process) { $recv = $process->read(); if ($recv) { echo "From Worker: " . $recv; } $process->write("HELLO worker {$process->pid}\n"); }); $process->write("hello worker[{$pid}]\n"); } }
function master_async($workers) { swoole_process::signal(SIGCHLD, function ($signo) use($workers) { while (1) { $ret = swoole_process::wait(false); if ($ret) { $pid = $ret['pid']; unset($workers[$pid]); echo "Worker Exit, PID=" . $pid . PHP_EOL; } else { break; } } }); /** * @var $process swoole_process */ foreach ($workers as $pid => $process) { swoole_event_add($process->pipe, function ($pipe) use($process) { $recv = $process->read(); if ($recv) { echo "From Worker: " . $recv; } }); $process->write("hello worker[{$pid}]\n"); } }
static function run() { $table = new swoole_table(1024 * 256); $table->column('index', swoole_table::TYPE_INT); $table->column('serid', swoole_table::TYPE_INT); $table->column('data', swoole_table::TYPE_STRING, 64); $table->create(); self::$table = $table; for ($i = 0; $i < self::$key_num; $i++) { $key = 'user_' . (self::$key_base + $i); $ret = self::$table->set($key, array('index' => $i, 'serid' => rand(1000, 9999), 'data' => "hello_world_{$i}")); if (!$ret) { echo "count {$i} failed."; break; } } for ($i = 0; $i < self::$worker_num; $i++) { $process = new swoole_process('UnitTest_Table::worker'); $process->start(); $workers[$i] = $process; } for ($i = 0; $i < self::$worker_num; $i++) { $exit = swoole_process::wait(); echo "worker[{$i}] exit\n"; } }
public function onWorkerStart(swoole_server $server, $worker_id) { swoole_process::signal(SIGCHLD, function ($sig) { //必须为false,非阻塞模式 while ($ret = swoole_process::wait(false)) { echo "PID={$ret['pid']}\n"; } }); }
private function master_run() { $event = event_new(); event_set($event, $this->socket_fd, EV_READ | EV_PERSIST, array($this, 'dispatch')); event_base_set($event, $this->event_base); event_add($event); event_base_loop($this->event_base); swoole_process::wait(); }
function master_async() { $count = 0; swoole_process::signal(SIGCHLD, function ($signo) use(&$count) { while (1) { $ret = swoole_process::wait(false); if ($ret) { $pid = $ret['pid']; $count++; //echo "Worker Exit, kill_signal={$ret['signal']} PID=" . $pid . PHP_EOL; //echo "Count=" . $count . " Worker_num=" . $this->worker_num . " Stauts=" . $this->status . PHP_EOL; if ($count == $this->worker_num) { switch ($this->status) { case '3-dim': $this->report_cost(); exit(0); break; case 'import': $this->report_cost(); $this->status = '1-dim'; $this->restart_process(); break; case '1-dim': $this->report_cost(); $this->status = '2-dim'; $this->restart_process(); break; case '2-dim': $this->report_cost(); $this->status = '3-dim'; $this->restart_process(); break; default: break; } $count = 0; } } else { break; } } }); /** * @var $process swoole_process */ foreach ($this->workers as $pid => $process) { swoole_event_add($process->pipe, function ($pipe) use($process) { $recv = $process->read(); if ($recv) { echo "From Worker: " . $recv; } $process->write("HELLO worker {$process->pid}\n"); }); $process->write("hello worker[{$pid}]\n"); } }
function callback_timer_function() { $Handle = new TimingCall_Tasks(); $Handle->upDaemonTime(); $tasks = $Handle->readExecuteTasks(); foreach ($tasks as $task) { $process = new swoole_process('callback_process_function', true); $process->write(json_encode($task)); $process->start(); $process->wait(false); } }
function onReceive($pipe) { global $workers; $worker = $workers[$pipe]; $data = $worker->read(); if ($data == false) { //表示子进程已关闭,回收它 $status = swoole_process::wait(); echo "Worker#{$status['pid']} exit\n"; } else { echo "RECV: " . $data; } }
/** * @brief 启动子进程 */ public function start() { $workerNum = $this->_objAha->getConfig()->get('aha', 'worker_num'); for ($i = 0; $i < $workerNum; $i++) { $worker = new \Daemon\Asyncworker($this->_objAha); $process = new \swoole_process(array($worker, 'start')); //$process->daemon(); $workerPid = $process->start(); $this->_workers[$workerPid] = $process; $process->write("worker started!"); } foreach ($this->_workers as $process) { $workerPid = \swoole_process::wait(); echo "[Worker Shutdown][WorkerId] {$workerPid} " . PHP_EOL; unset($this->_workers[$workerPid]); } }
protected function _waitChildProcess() { //必须为false,非阻塞模式 //信号发生时可能同时有多个子进程退出 //必须循环执行wait直到返回false $objManager = \Daemon\Library\Ipc\Manager::getInstance(); while ($result = \swoole_process::wait(false)) { $pid = $result['pid']; if ($objManager->hasDriveWorker($pid)) { $objManager->delDriveWorker($pid); \Daemon\Library\Ipc\Shared::delCurrentTaskTable($pid); if (!$this->_sigterm) { $objManager->createDriveWorker(\Daemon\Process\Master::getInstance()->getAha(), 1); } } elseif ($objManager->hasTaskWorker($pid)) { $objManager->delTaskWorker($pid); \Daemon\Library\Ipc\Shared::delCurrentTaskTable($pid); if (!$this->_sigterm) { $objManager->createDirtributeWorker(\Daemon\Process\Master::getInstance()->getAha(), 1); } } elseif ($objManager->hasRedoWorker($pid)) { $objManager->delRedoWorker($pid); \Daemon\Library\Ipc\Shared::delCurrentTaskTable($pid); if (!$this->_sigterm) { $objManager->createRedoWorker(\Daemon\Process\Master::getInstance()->getAha(), 1); } } elseif ($objManager->hasStatsWorker($pid)) { $objManager->delStatsWorker($pid); \Daemon\Library\Ipc\Shared::delCurrentTaskTable($pid); if (!$this->_sigterm) { $objManager->createStatsWorker(\Daemon\Process\Master::getInstance()->getAha(), 1); } } else { } } //如果是SIGTERM信号 并且子进程都已经退出了 父进程终止 $workers = \Daemon\Library\Ipc\Shared::getCurrentTaskTable(); if ($this->_sigterm && !$workers->count()) { \swoole_event_exit(); } }
static $index = 0; $index = $index + 1; $this->process->push($index . "Hello"); var_dump($index); if ($index == 10) { $this->process->push("exit"); $this->process->push("exit"); $this->process->push("exit"); swoole_timer_clear($timer_id); } }); } public function task_run($worker) { while (true) { $data = $worker->pop(); var_dump($data); if ($data == 'exit') { $worker->exit(); } sleep(5); } } } new BaseProcess(); swoole_process::signal(SIGCHLD, function ($sig) { //必须为false,非阻塞模式 while ($ret = swoole_process::wait(false)) { echo "PID={$ret['pid']}\n"; } });
function StartServ($phpStart, $cmd, $name) { $process = new swoole_process(function (swoole_process $worker) use($name, $cmd, $phpStart) { //目前指支持一个 $worker->exec($phpStart, array(STARTBASEPATH . "/lib/Swoole/shell/start.php", $cmd, $name)); //拉起server StartLogTimer(__LINE__ . ' ' . $phpStart . ' ' . STARTBASEPATH . '/lib/Swoole/shell/start.php ' . $cmd . ' ' . $name); }, false); $pid = $process->start(); $exeRet = swoole_process::wait(); if ($exeRet['code']) { //创建失败 StartLog(" startall [31;40m [FAIL] [0m" . PHP_EOL); return false; } else { StartLog(" startall [31;40m [SUCCESS] [0m" . PHP_EOL); return true; } }
public function eventAction() { $context_option['socket']['backlog'] = 1024; $context = stream_context_create($context_option); SwooleController::$socket = stream_socket_server('tcp://192.168.80.140:9021', $errno = 0, $errmsg = '', STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $context); // 尝试打开tcp的keepalive,关闭TCP Nagle算法 if (function_exists('socket_import_stream')) { $s = socket_import_stream(SwooleController::$socket); @socket_set_option($s, SOL_SOCKET, SO_KEEPALIVE, 1); @socket_set_option($s, SOL_SOCKET, TCP_NODELAY, 1); } stream_set_blocking(SwooleController::$socket, 0); #$socket = System_Socket::create(AF_INET,SOCK_STREAM,0); #SwooleController::$socket = $socket; /*$socket->bind('127.0.0.1',9021); $socket->listen(1024); #print_r($socket->listenfd()); SwooleController::$socket = $socket; SwooleController::$socket->setBlocking(false); */ echo "Master: parent, PID=" . posix_getpid() . "\n"; $workers = array(); $worker_num = 1; $worker_last = 0; function callback_function(swoole_process $worker) { echo "Worker: start. PID={$worker->pid}.\n"; echo "Worker: pipe={$worker->pipe}\n"; SwooleController::$event_base = event_base_new(); SwooleController::$event = event_new(); $GLOBALS['worker'] = $worker; function do_write($fd, $what, $arg) { SwooleController::$size--; $len = fwrite($fd, SwooleController::$send_str); event_del(SwooleController::$write_event[$arg]); unset(SwooleController::$write_event[$arg]); unset(SwooleController::$read_event[$arg]); fclose($fd); } function do_read($fd, $what, $arg) { $recv_buf = ''; while (1) { $buffer = fread($fd, 8192); #echo "123\n"; if ($buffer === '' || $buffer === false) { break; } $recv_buf .= $buffer; } #echo 'I have received that : '.$recv_buf; #fwrite(SwooleController::$client, " OK\n"); $write_event = event_new(); SwooleController::$write_event[$arg] = $write_event; event_set(SwooleController::$write_event[$arg], $fd, EV_WRITE | EV_PERSIST, 'do_write', $arg); event_base_set(SwooleController::$write_event[$arg], SwooleController::$event_base); event_add(SwooleController::$write_event[$arg]); #fclose(SwooleController::$client); event_del(SwooleController::$read_event[$arg]); } function do_accept($fd, $what, $arg) { $res = $GLOBALS['worker']->read(); #echo $res; $client = @stream_socket_accept(SwooleController::$socket, 0); stream_set_blocking($client, 0); $recv = $GLOBALS['worker']->write('0'); $read_event = event_new(); $idx = intval($read_event); #SwooleController::$client[$idx] = $client; SwooleController::$read_event[$idx] = $read_event; #print_r(SwooleController::$read_event); event_set(SwooleController::$read_event[$idx], $client, EV_READ | EV_PERSIST, 'do_read', $idx); event_base_set(SwooleController::$read_event[$idx], SwooleController::$event_base); event_add(SwooleController::$read_event[$idx]); /*$message= fread(SwooleController::$client, 8192); echo 'I have received that : '.$message; fwrite(SwooleController::$client, " OK\n"); fclose(SwooleController::$client);*/ #event_del(SwooleController::$event); } event_set(SwooleController::$event, $worker->pipe, EV_READ | EV_PERSIST, 'do_accept'); event_base_set(SwooleController::$event, SwooleController::$event_base); event_add(SwooleController::$event); event_base_loop(SwooleController::$event_base); } $event_base = event_base_new(); function do_listen_restart($pipe) { $res = SwooleController::$workers_pipe[$pipe]->read(); #echo $pipe."\n"; SwooleController::$stop = 0; } for ($i = 0; $i < SwooleController::$worker_num; $i++) { $process = new swoole_process('callback_function', false, true); $pid = $process->start(); SwooleController::$workers[$i] = $process; echo "Master: new worker, PID={$pid}\n"; SwooleController::$workers_pipe[$process->pipe] = $process; SwooleController::$restart_event[$i] = event_new(); event_set(SwooleController::$restart_event[$i], $process->pipe, EV_READ | EV_PERSIST, 'do_listen_restart'); event_base_set(SwooleController::$restart_event[$i], $event_base); event_add(SwooleController::$restart_event[$i]); /*swoole_event_add($process->pipe,function($pipe){ $read = SwooleController::$workers_pipe[$pipe]->read(); SwooleController::$stop = 0; });*/ } function do_dispatch() { if (!SwooleController::$stop) { #print_r('___'.SwooleController::$socket."\n"); $w_i = (SwooleController::$worker_last + 1) % SwooleController::$worker_num; SwooleController::$worker_last = $w_i; SwooleController::$workers[$w_i]->write('c'); SwooleController::$stop = 1; } } $event = event_new(); event_set($event, SwooleController::$socket, EV_READ | EV_PERSIST, 'do_dispatch'); event_base_set($event, $event_base); event_add($event); /*swoole_event_add(SwooleController::$socket,function ($fd){ #print_r("stop--->>>>".SwooleController::$stop."\n"); if (!SwooleController::$stop){ #print_r('___'.SwooleController::$socket."\n"); $w_i = (SwooleController::$worker_last+1)%SwooleController::$worker_num; SwooleController::$worker_last = $w_i; SwooleController::$workers[$w_i]->write('c'); SwooleController::$stop = 1; }else { #print_r("pipe_read_start\n"); #$read = SwooleController::$workers[SwooleController::$worker_last]->read(); #print_r("pipe_read--->>>>".$read."\n"); #SwooleController::$stop = $read; #echo 123; } #swoole_event_del($fd); });*/ event_base_loop($event_base); //swoole_event_wait(); swoole_process::wait(); }
public function __construct() { $this->process = new swoole_process(array($this, 'run'), false, 2); $this->process->start(); swoole_process::wait(); }
public function runAction(){ //根据max_id, currentIndex,安排job $this->calculateJob(); // 参数 -g 判断是否需要生成sitemap if($this->generate){ echo "Starting generating sitemaps..."; //生成一个sitemap的index文件 $this->generateSitemapIndex(); for($i = 0; $i < $this->worker_num; $i++){ $process = new swoole_process(array($this, 'generate')); // 传递job给子进程 if(isset($this->jobs[$i])){ $process->sitemap_job = $this->jobs[$i]; } $pid = $process->start(); $this->workers[$pid] = $process; } for($i = 0; $i < $this->worker_num; $i++) { //阻塞 $ret = swoole_process::wait(); $pid = $ret['pid']; unset($this->workers[$pid]); echo "Generator Worker Exit, PID=".$pid.PHP_EOL; } echo "Finishing generating sitemaps..."; } // 参数 -p 判断是否需要推送url // 一次提交100条,开4个进程, if($this->push){ echo "Starting pushing urls..."; for($i = 0; $i < $this->worker_num; $i++){ $process = new swoole_process(array($this, 'push')); // 传递job给子进程 if(isset($this->jobs[$i])){ $process->sitemap_job = $this->jobs[$i]; } $pid = $process->start(); $this->workers[$pid] = $process; } for($i = 0; $i < $this->worker_num; $i++) { //阻塞 $ret = swoole_process::wait(); $pid = $ret['pid']; unset($this->workers[$pid]); echo "Push Worker Exit, PID=".$pid.PHP_EOL; } echo "Finishing pushing urls..."; } }
/** * 注册信号 */ private static function register_signal() { swoole_process::signal(SIGTERM, function ($signo) { self::exit2p("收到退出信号,退出主进程"); }); swoole_process::signal(SIGCHLD, function ($signo) { while ($ret = swoole_process::wait(false)) { $pid = $ret['pid']; if (isset(self::$task_list[$pid])) { $task = self::$task_list[$pid]; if ($task["type"] == "crontab") { $end = microtime(true); $start = $task["start"]; $id = $task["id"]; Main::log_write("{$id} [Runtime:" . sprintf("%0.6f", $end - $start) . "]"); $task["process"]->close(); //关闭进程 unset(self::$task_list[$pid]); if (isset(self::$unique_list[$id]) && self::$unique_list[$id] > 0) { self::$unique_list[$id]--; } } if ($task["type"] == "worker") { $end = microtime(true); $start = $task["start"]; $classname = $task["classname"]; Main::log_write("{$classname}_{$task["number"]} [Runtime:" . sprintf("%0.6f", $end - $start) . "]"); $task["process"]->close(); //关闭进程 (new Worker())->create_process($classname, $task["number"], $task["redis"]); } } } }); swoole_process::signal(SIGUSR1, function ($signo) { //TODO something }); }
if (!class_exists('swoole_process')) { Console::put("no have swoole_process", true, true); } $server = new swoole_process(function ($process) { $php = $_SERVER['_']; return $process->exec($php, array(__DIR__ . "/../examples/server.php", 'daemon')); }, false, false); if (!$server->start()) { Console::put("Server start failed.", true, true); } usleep(200000); register_shutdown_function(function () { global $server; if (swoole_process::kill($server->pid, SIGTERM)) { Console::put("swoole_process::kill()"); $status = swoole_process::wait(); Console::put("swoole_process::wait()", !($status['pid'] == $server->pid)); } else { Console::put("swoole_process::kill()", true); } echo "------------------------------------------------------------------\n"; echo "Swoole UnitTest Finish.\n"; }); /** * UnitTests for swoole server. * This is just a client. Server see examples/server.php */ $client = new swoole_client(SWOOLE_TCP); if (!$client->connect('127.0.0.1', 9501)) { Console::put("swoole_client[TCP]->connect().", true, true); } else {
public function runAction() { //根据max_id, lastIndex,安排job $this->calculateJob(); //生成一个sitemap的index文件 $this->generateSitemapIndex(); exit; for ($i = 0; $i < $this->worker_num; $i++) { $process = new swoole_process(array($this, 'generate')); // 传递job给子进程 $process->sitemap_job = $this->jobs[$i]; $pid = $process->start(); $this->workers[$pid] = $process; } for ($i = 0; $i < $this->worker_num; $i++) { //阻塞 $ret = swoole_process::wait(); $pid = $ret['pid']; unset($this->workers[$pid]); echo "Worker Exit, PID=" . $pid . PHP_EOL; } }
function shellExec($script_file, $args) { if (!$this->process) { $this->process = new \swoole_process([$this, 'childProcess'], true, true); } $this->process->args = ['script_file' => $script_file, 'argv' => $args]; $this->process->start(); $output = ''; while (true) { $read = $this->process->read(); if ($read) { $output .= $read; } else { \swoole_process::wait(); break; } } return $output; }
function StartServ($phpStart, $cmd, $name) { $process = new swoole_process(function (swoole_process $worker) use($name, $cmd, $phpStart) { //目前指支持一个 $worker->exec($phpStart, array(STARTBASEPATH . "/lib/Swoole/shell/start.php", $cmd, $name)); //拉起server StartLogTimer(__LINE__ . ' ' . $phpStart . ' ' . STARTBASEPATH . '/lib/Swoole/shell/start.php ' . $cmd . ' ' . $name); }, false); $pid = $process->start(); $exeRet = swoole_process::wait(); return; }
/** *注册监听的信号 */ private static function registerSignal() { swoole_process::signal(SIGCHLD, function ($signo) { //SIGCHLD,子进程结束时,父进程会收到这个信号 //这里可以做任务执行完后的事情,比如:改变任务状态,统计任务执行时间 while ($status = swoole_process::wait(false)) { $task = self::$taskList[$status['pid']]; $startTime = $task['start']; self::updateTasks($task); $runTime = time() - $startTime; Main::log($task['task']['name'] . "执行了" . $runTime . "秒"); unset(self::$taskList[$status['pid']]); } }); swoole_process::signal(SIGINT, function ($signo) { self::resetStatus(); unlink(Main::$pidFile); exit; }); swoole_process::signal(SIGUSR1, function () { self::init(); }); }
/** * listen on task * * @param $serv * @param $task_id * @param $from_id * @param $param * @return string */ public function on_task(\swoole_server $serv, $task_id, $from_id, $param) { $param = str_replace(self::EOFF, '', $param); $param = unserialize($param); $fd = $param['fd']; $data = $param['data']; // call model $back = $this->_dispatch($data, $serv, $fd); // dont send back if (empty($data['return']) || $data['return'] === TRUE) { $back = serialize($back); $back .= self::EOFF; $serv->send($fd, $back); } // close connect $serv->close($fd); // waite for process end while (@\swoole_process::wait()) { } return $back; }
/** * @param int $worker_num * @param bool $daemon * @throws Exception\NotFound */ function runWorker($worker_num = 1, $daemon = false) { if ($worker_num > 1 or $daemon) { if (!class_exists('\\swoole\\process')) { throw new Exception\NotFound("require swoole extension"); } if ($worker_num < 0 or $worker_num > 1000) { $worker_num = 200; } } else { $this->_atomic = new \swoole_atomic(1); $this->_worker(); return; } if ($daemon) { \swoole_process::daemon(); } $this->_atomic = new \swoole_atomic(1); for ($i = 0; $i < $worker_num; $i++) { $process = new \swoole\process(array($this, '_worker'), false, false); $process->start(); $this->_workers[] = $process; } \swoole_process::signal(SIGCHLD, function () { while (true) { $exitProcess = \swoole_process::wait(false); if ($exitProcess) { foreach ($this->_workers as $k => $p) { if ($p->pid == $exitProcess['pid']) { if ($this->_atomic->get() == 1) { $p->start(); } else { unset($this->_workers[$k]); if (count($this->_workers) == 0) { swoole_event_exit(); } } } } } else { break; } } }); \swoole_process::signal(SIGTERM, function () { //停止运行 $this->_atomic->set(0); }); }
<?php const WORK_NUM = 250; for ($i = 0; $i < WORK_NUM; $i++) { $process = new swoole_process(function ($worker) { $worker->exec("/usr/bin/php", array("/mnt/hgfs/work/swoole/swoole_task/chat_room/client.php")); }); $process->start(); } for ($i = 0; $i < WORK_NUM; $i++) { swoole_process::wait(); // 回收结束运行的子进程 }
/** * @param bool $blocking * @return array */ function process_wait($blocking = true) { return swoole_process::wait($blocking); }