视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
php进程通信有几种方式
2020-11-27 15:21:07 责编:小采
文档
 php进行进程间通信的方式有好几种:管道(Pipe)及有名管道(named pipe)、信号(Signal)、报文(Message)队列(消息队列)、共享内存、信号量(semaphore)、套接口(Socket)。

本文列举一个进行介绍,那就是是通过有名管道的方式。

管道用于承载简称之间的通讯数据。为了方便理解,可以将管道比作文件,进程A将数据写到管道P中,然后进程B从管道P中读取数据。

php提供的管道操作API与操作文件的API基本一样,除了创建管道使用posix_mkfifo函数,读写等操作均与文件操作函数相同。

当然,你可以直接使用文件模拟管道,但是那样无法使用管道的特性了。

通过管道通信的大概思路是,首先创建一个管道,然后子进程向管道中写入信息,父进程从管道中读取信息,这样就可以做到父子进程直接实现通信了。

<?php
/**
 * author: NickBai
 * createTime: 2016/12/2 0002 上午 11:12
 */
//创建管道
$pipePath = "/tmp/test.pipe";
if( !file_exists( $pipePath ) ){
 if( !posix_mkfifo( $pipePath, 0666 ) ){
 exit('make pipe false!' . PHP_EOL);
 }
}
//创建进程,子进程写管道,父进程读管道
$pid = pcntl_fork();
if( $pid == 0 ){
 //子进程写管道
 $file = fopen( $pipePath, 'w' );
 fwrite( $file, 'hello world' );
 sleep(1);
 exit();
}else{
 //父进程读管道
 $file = fopen( $pipePath, 'r' );
 //stream_set_blocking( $file, False ); //设置成读取非阻塞
 echo fread( $file, 20 ) . PHP_EOL;
 pcntl_wait($status); //回收子进程
}

注意:本代码只能在linux下运行,并且只能在php-cli模式下。

第7行:指定一个管道的路径,这里跟普通文件没什么区别。

第9行:通过 posix_mkfifo 函数创建 管道 并且设置读写权限为 0666

第15行:通过 pcntl_fork函数创建一个子进程。注意从现在开始,程序将会被分成两个进程来执行。 pcntl_fork 函数 很特殊,它调用一次拥有 多个返回值。在父进程中:它返回 子进程的ID 这个值是 大于0 的。在子进程中,它返回0。当返回 -1 时表示创建进程失败。

第17行:两个进程根据当前进程所获得的$pid的值不同,而进入不同的分支。

第18~22行:子进程打开管道,并向其中写入hello world ,然后进入休眠,休眠结束之后,退出。

第25~29行:父进程打开管道,并进行读取,最后执行 29行的代码回收掉子进程。这里面两个地方是阻塞的,首先是默认读的地方,要等待子进程发出exit命令之后,才能返回数据。还有就是回收进程的 pcntl_wait方法。要等到进程退出。

下载本文
显示全文
专题