php有名管道,php多进程通信,有名管道(pcntl学习 五)

对于多进程间的通信,研究了一天的管道,封装了一个管道类,以及处理多进程的类。管道的理论,后期再补上,先上代码。

/**

* 管道封装类

*

* @author mingazi@163.com

* @link www.helloworldcoding.com

* @since 2017-04-18

*/

class fifoPipeClass

{

/**

* 管道资源

*/

protected $handler;

/**

* 管道路径

*/

protected $path;

/**

* 是否阻塞,false为非阻塞,true为阻塞

*/

protected $block = false;

/**

* 创建管道

*/

public function __construct($path = './weicool.pipe', $cover = false, $mode = 0666)

{

if (file_exists($path)) {

if ($cover) {

unlink($path);

} else {

$this->path = $path;

return $this;

}

}

if (posix_mkfifo($path,$mode)) {

$this->path = $path;

return $this;

} else {

$this->throwException('create pipe failed');

}

}

/**

* 抛异常方法

*/

public function throwException($msg = 'failed')

{

throw new \Exception($msg);

}

/**

* 设置阻塞方式

*

* @param bool $block false为非阻塞,true为阻塞

*/

public function setBlock($block = false)

{

$this->block = $block;

}

/**

* 指定pipe文件路径

*/

public function setPath($path)

{

if (!file_exists($path)) {

$msg = $path.' pipe does not exists';

$this->throwException($msg);

}

$this->path = $path;

}

/**

* 获取pipe文件路径

*/

public function getPath()

{

return $this->path;

}

/**

* 打开一个管道

*

* @param string $mode 打开类型

*/

public function pipeOpen($mode = 'r')

{

$handler = fopen($this->path, $mode);

if (!is_resource($handler)) {

$msg = 'open pipe '.$this->path.' falied';

$this->throwException($msg);

}

// 设置阻塞类型

stream_set_blocking($handler, $this->block);

$this->handler = $handler;

return $this;

}

/**

* 已读的方式打开管道

*

* @return resource

*/

public function readOpen()

{

return $this->pipeOpen('r');

}

/**

* 已写的方式打开管道

*

* @return resource

*/

public function writeOpen()

{

return $this->pipeOpen('w');

}

/**

* 读取一行,或给定的长度

*/

public function readOne($byte = 1024)

{

$data = fread($this->handler,$byte);

return $data;

}

/**

* 读取所有的内容

*/

public function readAll()

{

$hd = $this->handler;

$data = '';

while (!feof($hd)) {

$data .= fread($hd,1024);

}

return $data;

}

/**

* 写入数据

*/

public function write($data)

{

$hd = $this->handler;

try {

fwrite($hd,$data);

} catch(\Exception $e) {

$this->throwException($e->getMessage());

}

return $this;

}

/**

* 关闭管道

*/

public function close()

{

return fclose($this->handler);

}

/**

* 删除管道

*/

public function remove()

{

return unlink($this->path);

}

}

多进程处理类,利用管道保存各个进程的返回结果,主进程处理最后的结果

require_once './fifoPipeClass.php';

class pipeMultiProcess

{

protected $process = []; // 子进程

protected $child = []; // 子进程pid数组

protected $result = []; // 计算的结果

public function __construct($process = [])

{

$this->process = $process;

}

/**

* 设置子进程

*/

public function setProcess($process)

{

$this->process = $process;

}

/**

* fork 子进程

*/

public function forkProcess()

{

$process = $this->process;

foreach($process as $k => $item) {

$pid = pcntl_fork();

if ($pid == 0) {

$pipe = new fifoPipeClass();

$id = getmypid();

$pipe->writeOpen();

$pipe->write($k.' pid:'.$id.PHP_EOL);

$pipe->close();

exit(0);

} else if ($pid > 0) {

$this->child[] = $pid;

}

}

return $this;

}

/**

* 等待子进程结束

*/

public function waiteProcess()

{

$child = $this->child;

$pipe = new fifoPipeClass();

$pipe->readOpen();

echo 'get all begin'.PHP_EOL;

while(count($child)) {

foreach($child as $k => $pid){

$res = pcntl_waitpid($pid,$status,WNOHANG);

if ( -1 == $res || $res > 0 ) {

unset($child[$k]);

}

}

$data = $pipe->readOne();

if ($data) {

$this->result[] = $data;

}

}

$pipe->close();

echo 'get all end'.PHP_EOL;

$pipe->remove();

return $this;

}

/**

* 获取返回结果

*/

public function getResult()

{

return $this->result;

}

}

$obj = new pipeMultiProcess();

$obj->setProcess(['name'=>1,'age'=>2,'sex'=>3]);

$res = $obj->forkProcess()->waiteProcess()->getResult();

print_r($res);

运行结果如下:

Array

(

[0] => age pid:7436

[1] => sex pid:7437

name pid:7435

)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值