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 相关文章推荐
一个多文件上传的例子(原创)
Oct 09 PHP
如何使用脚本模仿登陆过程
Nov 22 PHP
一个php导出oracle库的php代码
Apr 20 PHP
PHP 加密解密内部算法
Apr 22 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十二)
Jun 25 PHP
PHP中的替代语法介绍
Jan 09 PHP
php基于curl扩展制作跨平台的restfule 接口
May 11 PHP
变量在 PHP7 内部的实现(二)
Dec 21 PHP
PHP中FTP相关函数小结
Jul 15 PHP
PHP实践教程之过滤、验证、转义与密码详解
Jul 24 PHP
thinkPHP5框架接口写法简单示例
Aug 05 PHP
关于php开启错误提示的总结
Sep 24 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
4月1日重磅发布!《星际争霸II》6.0.0版本更新
2020/04/09 星际争霸
基于asp+ajax和数据库驱动的二级联动菜单
2010/05/06 PHP
PHP关于IE下的iframe跨域导致session丢失问题解决方法
2013/10/10 PHP
destoon官方标签大全
2014/06/20 PHP
PHP提示Cannot modify header information - headers already sent by解决方法
2014/09/22 PHP
PHP开发Apache服务器配置
2015/07/15 PHP
smarty高级特性之过滤器的使用方法
2015/12/25 PHP
PHP检查端口是否可以被绑定的方法示例
2018/08/09 PHP
ThinkPHP中图片按比例切割的代码实例
2019/03/08 PHP
PHP字符串中抽取子串操作实例分析
2019/06/22 PHP
实用框架(iframe)操作代码
2014/10/23 Javascript
图文详解Heap Sort堆排序算法及JavaScript的代码实现
2016/05/04 Javascript
jQuery插件MovingBoxes实现左右滑动中间放大图片效果
2017/02/28 Javascript
微信小程序图片选择、上传到服务器、预览(PHP)实现实例
2017/05/11 Javascript
使用cookie绕过验证码登录的实现代码
2017/10/12 Javascript
JS实现自定义状态栏动画文字效果示例
2017/10/12 Javascript
vue的常用组件操作方法应用分析
2018/04/13 Javascript
vue.js 2.0实现简单分页效果
2019/07/29 Javascript
JS实现联想、自动补齐国家或地区名称的功能
2020/07/07 Javascript
Python实现的Kmeans++算法实例
2014/04/26 Python
对Python 2.7 pandas 中的read_excel详解
2018/05/04 Python
Python从函数参数类型引出元组实例分析
2019/05/28 Python
pandas中的series数据类型详解
2019/07/06 Python
OpenCV Python实现拼图小游戏
2020/03/23 Python
python json.dumps中文乱码问题解决
2020/04/01 Python
亚洲在线旅行门户网站:Expedia.com.hk(智游网)
2020/04/14 全球购物
西班牙品牌鞋子、服装和配饰在线商店:Esdemarca
2021/02/17 全球购物
个人找工作求职简历的自我评价
2013/10/20 职场文书
商务英语专业求职信
2014/06/26 职场文书
党支部创先争优承诺书
2014/08/30 职场文书
2014年高中生自我评价范文
2014/09/26 职场文书
考试作弊检讨书
2014/10/21 职场文书
2014年信用社工作总结
2014/11/25 职场文书
亮剑观后感500字
2015/06/05 职场文书
python实现MD5进行文件去重的示例代码
2021/07/09 Python
【DOTA2】高能暴走TK秀!PSG LGD vs ASTER - DPC 2022 WINTER TOUR CN
2022/04/02 DOTA