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与javascript对多项选择的处理
Oct 09 PHP
php判断字符以及字符串的包含方法属性
Aug 30 PHP
基于HTTP长连接的"服务器推"技术的php 简易聊天室
Oct 31 PHP
php删除文件夹及其文件夹下所有文件的函数代码
Jan 23 PHP
PHP 正则判断中文UTF-8或GBK的思路及具体实现
Nov 26 PHP
PHP中使用json数据格式定义字面量对象的方法
Aug 20 PHP
PHP图片处理之图片旋转和图片翻转实例
Nov 19 PHP
php中explode的负数limit用法分析
Feb 27 PHP
PHP正则匹配到2个字符串之间的内容方法
Dec 24 PHP
php + WebUploader实现图片批量上传功能
May 06 PHP
Laravel 添加多语言提示信息的方法
Sep 29 PHP
PHP实现创建以太坊钱包转账等功能
Apr 21 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
PHP中通过ADO调用Access数据库的方法测试不通过
2006/12/31 PHP
php做下载文件的实现代码及文件名中乱码解决方法
2011/02/03 PHP
PHP中数组合并的两种方法及区别介绍
2012/09/14 PHP
如何使用php判断服务器是否是HTTPS连接
2013/07/05 PHP
利用curl抓取远程页面内容的示例代码
2013/07/23 PHP
ThinkPHP中公共函数路径和配置项路径的映射分析
2014/11/22 PHP
php和editplus正则表达式去除空白行
2015/04/17 PHP
php集成动态口令认证
2016/07/21 PHP
PHP下 Mongodb 连接远程数据库的实例代码
2017/08/30 PHP
php适配器模式简单应用示例
2019/10/23 PHP
让textarea控件的滚动条怎是位与最下方
2007/04/20 Javascript
基于mootools 1.3框架下的图片滑动效果代码
2011/04/22 Javascript
推荐6款基于jQuery实现图片效果插件
2014/12/07 Javascript
javascript插件开发的一些感想和心得
2016/02/28 Javascript
前端面试知识点锦集(JavaScript篇)
2016/12/28 Javascript
微信小程序图片选择区域裁剪实现方法
2017/12/02 Javascript
vue组件通信传值操作示例
2019/01/08 Javascript
jQuery实现容器间的元素拖拽功能
2020/12/01 jQuery
[44:41]Fnatic vs Liquid 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Python3.x版本中新的字符串格式化方法
2015/04/24 Python
python实现基于SVM手写数字识别功能
2020/05/27 Python
解决Python内层for循环如何break出外层的循环的问题
2019/06/24 Python
详解解决Python memory error的问题(四种解决方案)
2019/08/08 Python
docker-py 用Python调用Docker接口的方法
2019/08/30 Python
python3 tkinter实现添加图片和文本
2019/11/26 Python
详解Python的爬虫框架 Scrapy
2020/08/03 Python
奥地利购买珠宝和手表网站:ELLA JUWELEN
2019/09/03 全球购物
铭立家具面试题
2012/12/06 面试题
元旦晚会策划方案
2014/02/18 职场文书
简单的项目建议书模板
2014/03/12 职场文书
法人单位适用的授权委托书
2014/09/19 职场文书
交通局领导班子群众路线教育实践活动对照检查材料思想汇报
2014/10/09 职场文书
意外死亡赔偿协议书
2014/10/14 职场文书
网络销售员岗位职责
2015/04/11 职场文书
Golang生成Excel文档的方法步骤
2021/06/09 Golang
解决MySQL报“too many connections“错误
2022/04/19 MySQL