網(wǎng)站做法外貿(mào)海外推廣
swoole文檔:Swoole 文檔
process子進(jìn)程和父進(jìn)程之間通信,依靠監(jiān)聽(tīng)。子進(jìn)程和父進(jìn)程分別做監(jiān)聽(tīng)。父進(jìn)程寫入信息,子進(jìn)程監(jiān)聽(tīng)接收。子進(jìn)程向父進(jìn)程寫入,調(diào)用父進(jìn)程監(jiān)聽(tīng)。
子進(jìn)程向父進(jìn)程寫入信息有兩種方式,一種調(diào)用write寫入管道,一種是直接輸出寫入管道。在創(chuàng)建進(jìn)程的時(shí)候控制。
一 調(diào)用write寫入管道
function test3()
{$p = new Swoole\Process(function ($worker) {Swoole\Event::add($worker->pipe, function () use ($worker) {$data = $worker->read();echo "sub:" . $data . PHP_EOL;$data = 'worker:' . $data;$worker->write($data); //寫入父線程 2});}, false, 2);$p->start();Swoole\Event::add($p->pipe, function () use ($p) {$data = $p->read();echo 'P:' . $data . PHP_EOL; //最終輸出 3});$p->write('123'); //請(qǐng)求子線程 1
}
test3();
sub:123
P:worker:123
二 直接輸出到管道
function test2()
{$p = new Swoole\Process(function ($worker) {Swoole\Event::add($worker->pipe, function () use ($worker) {$data = $worker->read();echo 'worker:' . $data . PHP_EOL; //直接寫入父線程 2});}, true, 2);$p->start();Swoole\Event::add($p->pipe, function () use ($p) {$data = $p->read();echo 'P:' . $data . PHP_EOL; //最終輸出 3});$p->write('123'); //請(qǐng)求子線程 1
}
test2();
P:worker:123
新建process之后,在其回調(diào)中創(chuàng)建的監(jiān)聽(tīng)是子進(jìn)程的監(jiān)聽(tīng),使用其對(duì)象創(chuàng)建的監(jiān)聽(tīng)是父進(jìn)程的監(jiān)聽(tīng)。
三 其他
其實(shí)子進(jìn)程不做監(jiān)聽(tīng)也能收到父進(jìn)程發(fā)送的信息,但是直接讀信息和監(jiān)聽(tīng)都存在的情況下,先執(zhí)行直接讀取的,可能監(jiān)聽(tīng)不會(huì)執(zhí)行。根據(jù)文檔,監(jiān)聽(tīng)必須在線程啟動(dòng)后設(shè)置。根據(jù)查的資料,event觸發(fā)條件是句柄文件的改變,即類似于例子中的$p->pipe改變,否則不會(huì)觸發(fā)。
使用event監(jiān)聽(tīng)是異步的??吹絙站上有個(gè)例子代碼如下
public function onMessage(Swoole\WebSocket\Server $server, Swoole\WebSocket\Frame $frame){$data = $frame->data;$data = json_decode($data);$cmd = $data['cmd']; //命令$fd = $frame->fd;$is_block = isset($data['is_block']) ? $data['is_block'] : 0;if ($is_block) {if (isset($this->process_list[$fd])) {$process = $this->process_list[$fd];} else {//新建子進(jìn)程$process = new Swoole\Process([$this, 'do_time_process'], true, 2);$process->start();$this->process_list[$fd] = $process;Swoole\Event::add($process->pipe, function () use ($process, $frame) {$data = $process->read();$this->server->push($frame->fd, $data);});}$process->write($cmd);sleep(1);} else {$this->process->write($cmd);$data = $this->process->read();$this->server->push($frame->fd, $data);}}//子進(jìn)程public function do_time_process(Swoole\Process $worker){$cmd = $worker->read();//函數(shù)打開(kāi)進(jìn)程文件指針。打開(kāi)一個(gè)指向進(jìn)程的管道,該進(jìn)程由派生指定的 command 命令執(zhí)行而產(chǎn)生$handle = popen($cmd, 'r');Swoole\Event::add($worker->pipe, function () use ($worker, $handle) {$cmd = $worker->read();if ('exit' == $cmd) {$worker->exit();}//向管道寫入內(nèi)容fwrite($handle, $cmd);});//feof() 函數(shù)檢查是否已到達(dá)文件末尾(EOF)while (!feof($handle)) {$str = fread($handle, 18192);$worker->write($str); //向父進(jìn)程寫入//echo $str;}}
do_time_process中設(shè)置event監(jiān)聽(tīng)的目的是,在執(zhí)行不會(huì)自己結(jié)束的命令時(shí),可以再次設(shè)置命令執(zhí)行退出等操作。比如linux中ping命令。還沒(méi)測(cè)試好,本來(lái)想寫個(gè)例子試試,但是按照以上內(nèi)容寫的,子進(jìn)程中的監(jiān)聽(tīng)一直沒(méi)有被觸發(fā)。
四 參考
【swoole 入門課程】https://www.bilibili.com/video/BV1dt411a7Tb?p=4&vd_source=f1bd3b5218c30adf0a002c8c937e0a27
swoole_event_add · Swoole文檔 · 看云
PHP swoole的process模塊創(chuàng)建和使用子進(jìn)程操作示例_php技巧_腳本之家
帶你學(xué)習(xí)swoole_process詳解 · php開(kāi)發(fā)筆記 · 看云