PHP共享内存用法实例分析


Posted in PHP onFebruary 12, 2016

本文实例讲述了PHP共享内存用法。分享给大家供大家参考,具体如下:

共享内存主要用于进程间通信

php中的共享内存有两套扩展可以实现

1、shmop  编译时需要开启 --enable-shmop 参数

实例:

$shm_key = ftok(__FILE__, 't');
/**
 开辟一块共享内存
int $key , string $flags , int $mode , int $size 
$flags: a:访问只读内存段
    c:创建一个新内存段,或者如果该内存段已存在,尝试打开它进行读写
    w:可读写的内存段
    n:创建一个新内存段,如果该内存段已存在,则会失败
$mode: 八进制格式 0655
$size: 开辟的数据大小 字节
 */
$shm_id = shmop_open($shm_key, "c", 0644, 1024);
/**
 * 写入数据 数据必须是字符串格式 , 最后一个指偏移量
 * 注意:偏移量必须在指定的范围之内,否则写入不了
 * 
 */
$size = shmop_write($shm_id, 'songjiankang', 0);
echo "write into {$size}";
#读取的范围也必须在申请的内存范围之内,否则失败
$data = shmop_read($shm_id, 0, 100);
var_dump($data);
#删除 只是做一个删除标志位,同时不在允许新的进程进程读取,当在没有任何进程读取时系统会自动删除
shmop_delete($shm_id);
#关闭该内存段
shmop_close($shm_id);

2、用 Semaphore 扩展中的 sem 类函数 (用起来更方便,类似 key-value 格式)

// Get the file token key
$key = ftok(__DIR__, 'a');
// 创建一个共享内存
$shm_id = shm_attach($key, 1024, 777); // resource type
if ($shm_id === false) {
  die('Unable to create the shared memory segment');
}
#设置一个值
shm_put_var($shm_id, 111, 'value');
#删除一个key
//shm_remove_var($shm_id, 111);
#获取一个值
$value = shm_get_var($shm_id, 111);
var_dump($value);
#检测一个key是否存在
// var_dump(shm_has_var($shm_id, 111));
#从系统中移除
shm_remove($shm_id);
#关闭和共享内存的连接
shm_detach($shm_id);

注意:这两种方式不通用的

一个用共享内存和信号量实现的消息队列

/**
* 使用共享内存和信号量实现
* 
* 支持多进程, 支持各种数据类型的存储
* 注: 完成入队或出队操作,尽快使用unset(), 以释放临界区
*
*/
class ShmQueue
{
  private $maxQSize = 0; // 队列最大长度
  private $front = 0; // 队头指针
  private $rear = 0; // 队尾指针
  private $blockSize = 256; // 块的大小(byte)
  private $memSize = 25600; // 最大共享内存(byte)
  private $shmId = 0;
  private $filePtr = './shmq.ptr';
  private $semId = 0;
  public function __construct ()
  {
    $shmkey = ftok(__FILE__, 't');
    $this->shmId = shmop_open($shmkey, "c", 0644, $this->memSize);
    $this->maxQSize = $this->memSize / $this->blockSize;
    // 申?一个信号量
    $this->semId = sem_get($shmkey, 1);
    sem_acquire($this->semId); // 申请进入临界区
    $this->init();
  }
  private function init ()
  {
    if (file_exists($this->filePtr)) {
      $contents = file_get_contents($this->filePtr);
      $data = explode('|', $contents);
      if (isset($data[0]) && isset($data[1])) {
        $this->front = (int) $data[0];
        $this->rear = (int) $data[1];
      }
    }
  }
  public function getLength ()
  {
    return (($this->rear - $this->front + $this->memSize) % ($this->memSize)) /
         $this->blockSize;
  }
  public function enQueue ($value)
  {
    if ($this->ptrInc($this->rear) == $this->front) { // 队满
      return false;
    }
    $data = $this->encode($value);
    shmop_write($this->shmId, $data, $this->rear);
    $this->rear = $this->ptrInc($this->rear);
    return true;
  }
  public function deQueue ()
  {
    if ($this->front == $this->rear) { // 队空
      return false;
    }
    $value = shmop_read($this->shmId, $this->front, $this->blockSize - 1);
    $this->front = $this->ptrInc($this->front);
    return $this->decode($value);
  }
  private function ptrInc ($ptr)
  {
    return ($ptr + $this->blockSize) % ($this->memSize);
  }
  private function encode ($value)
  {
    $data = serialize($value) . "__eof";
    echo '';
    echo strlen($data);
    echo '';
    echo $this->blockSize - 1;
    echo '';
    if (strlen($data) > $this->blockSize - 1) {
      throw new Exception(strlen($data) . " is overload block size!");
    }
    return $data;
  }
  private function decode ($value)
  {
    $data = explode("__eof", $value);
    return unserialize($data[0]);
  }
  public function __destruct ()
  {
    $data = $this->front . '|' . $this->rear;
    file_put_contents($this->filePtr, $data);
    sem_release($this->semId); // 出临界区, 释放信号量
  }
}
/*
 * // 进队操作 $shmq = new ShmQueue(); $data = 'test data'; $shmq->enQueue($data);
 * unset($shmq); // 出队操作 $shmq = new ShmQueue(); $data = $shmq->deQueue();
 * unset($shmq);
 */

linux下 用 ipc命令查看 ,用 ipcrm 命令可以删除

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP函数utf8转gb2312编码
Dec 21 PHP
php session 错误
May 21 PHP
解析PHPExcel使用的常用说明以及把PHPExcel整合进CI框架的介绍
Jun 24 PHP
PHP调用MsSQL Server 2012存储过程获取多结果集(包含output参数)的详解
Jul 03 PHP
php递归方法实现无限分类实例代码
Feb 28 PHP
解密ThinkPHP3.1.2版本之模板继承
Jun 19 PHP
PHP中比较时间大小实例
Aug 21 PHP
PHP实现抓取Google IP并自动修改hosts文件
Feb 12 PHP
PHP大神的十大优良习惯
Sep 14 PHP
Yii 2.0在Grid中格式化时间方法示例
Jun 06 PHP
Laravel框架使用Seeder实现自动填充数据功能
Jun 13 PHP
open_basedir restriction in effect. 原因与解决方法
Mar 14 PHP
PHP连接MSSQL方法汇总
Feb 05 #PHP
Symfony2开发之控制器用法实例分析
Feb 05 #PHP
Symfony2实现在doctrine中内置数据的方法
Feb 05 #PHP
PHP MYSQL实现登陆和模糊查询两大功能
Feb 05 #PHP
twig模板获取全局变量的方法
Feb 05 #PHP
twig里使用js变量的方法
Feb 05 #PHP
Symfony2安装第三方Bundles实例详解
Feb 04 #PHP
You might like
从零开始的异世界生活:第二季延期后,B站上架了第二部剧场版
2020/05/06 日漫
snoopy PHP版的网络客户端提供本地下载
2008/04/15 PHP
递归删除一个节点以及该节点下的所有节点示例
2014/03/19 PHP
使用php语句将数据库*.sql文件导入数据库
2014/05/05 PHP
浅谈php和js中json的编码和解码
2016/10/24 PHP
laravel 验证错误信息到 blade模板的方法
2019/09/29 PHP
腾讯UED 漂亮的提示信息效果代码
2011/09/12 Javascript
利用a标签自动解析URL分析网址实例
2014/10/20 Javascript
JavaScript常用脚本汇总(一)
2015/03/04 Javascript
javascript实现获取服务器时间
2015/05/19 Javascript
图解js图片轮播效果
2015/12/20 Javascript
javascript的正则匹配方法学习
2016/02/24 Javascript
原生JavaScript实现Ajax异步请求
2017/11/19 Javascript
angular2中使用第三方js库的实例
2018/02/26 Javascript
详解express + mock让前后台并行开发
2018/06/06 Javascript
jQuery pager.js 插件动态分页功能实例分析
2019/08/02 jQuery
js实现表格数据搜索
2020/08/09 Javascript
解决vue+webpack项目接口跨域出现的问题
2020/08/10 Javascript
[02:46]2014DOTA2国际邀请赛 选手为你解读比赛MVP充满梦想
2014/07/09 DOTA
运动检测ViBe算法python实现代码
2018/01/09 Python
如何使用 Pylint 来规范 Python 代码风格(来自IBM)
2018/04/06 Python
python学生管理系统学习笔记
2019/03/19 Python
python中报错"json.decoder.JSONDecodeError: Expecting value:"的解决
2019/04/29 Python
python对常见数据类型的遍历解析
2019/08/27 Python
OpenCV+face++实现实时人脸识别解锁功能
2019/08/28 Python
Python request中文乱码问题解决方案
2020/09/17 Python
属性与 @property 方法让你的python更高效
2020/09/21 Python
Booking.com德国:预订最好的酒店和住宿
2020/02/16 全球购物
初中生学习的自我评价
2013/11/14 职场文书
全民健身日活动方案
2014/01/29 职场文书
大学生活动总结模板
2014/07/02 职场文书
大学生交通专业求职信
2014/09/01 职场文书
2016简历自荐信优秀范文
2016/01/29 职场文书
go语言中GOPATH GOROOT的作用和设置方式
2021/05/05 Golang
安装配置mysql及Navicat prenium的详细流程
2021/06/10 MySQL
Python初学者必备的文件读写指南
2021/06/23 Python