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 相关文章推荐
phpMyAdmin 安装及问题总结
May 28 PHP
PHP中for与foreach的区别分析
Mar 09 PHP
PHP5 的对象赋值机制介绍
Aug 02 PHP
php array的学习笔记
May 16 PHP
浅析Apache中RewriteCond规则参数的详细介绍
Jun 30 PHP
php之curl设置超时实例
Nov 03 PHP
yii2中结合gridview如何使用modal弹窗实例代码详解
Jun 12 PHP
php中文乱码问题的终极解决方案汇总
Aug 01 PHP
PHP对称加密算法(DES/AES)类的实现代码
Nov 14 PHP
PHP CURL与java http使用方法详解
Jan 26 PHP
php生成静态页面并实现预览功能
Jun 27 PHP
PHP7创建COOKIE和销毁COOKIE的实例方法
Feb 03 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
怎样在UNIX系统下安装php3
2006/10/09 PHP
随时给自己贴的图片加文字的php代码
2007/03/08 PHP
php 注册时输入信息验证器的实现详解
2013/07/05 PHP
ThinkPHP3.1.3版本新特性概述
2014/06/19 PHP
php查询mssql出现乱码的解决方法
2014/12/29 PHP
Linux php 中文乱码的快速解决方法
2016/05/13 PHP
PHP在同一域名下两个不同的项目做独立登录机制详解
2017/09/22 PHP
Web前端设计模式  制作漂亮的弹出层
2010/10/29 Javascript
php与js的区别是什么
2013/08/05 Javascript
Ajax同步与异步传输的示例代码
2013/11/21 Javascript
node.js中的fs.mkdir方法使用说明
2014/12/17 Javascript
JS+CSS实现淡入式焦点图片幻灯切换效果的方法
2015/02/26 Javascript
JavaScript实现控制打开文件另存为对话框的方法
2015/04/17 Javascript
jquery操作checkbox火狐下第二次无法勾选的解决方法
2016/10/10 Javascript
微信小程序的生命周期的详解
2017/10/19 Javascript
vue、react等单页面项目部署到服务器的方法及vue和react的区别
2018/09/29 Javascript
jQuery设置下拉框显示与隐藏效果的方法分析
2019/09/15 jQuery
vue之debounce属性被移除及处理详解
2019/11/13 Javascript
vue keep-alive列表页缓存 详情页返回上一页不刷新,定位到之前位置
2019/11/26 Javascript
微信小程序自定义顶部组件customHeader的示例代码
2020/06/03 Javascript
[01:33]完美世界DOTA2联赛PWL S3 集锦第二期
2020/12/21 DOTA
python实现DNS正向查询、反向查询的例子
2014/04/25 Python
Python最基本的输入输出详解
2015/04/25 Python
PyQt5重写QComboBox的鼠标点击事件方法
2019/06/25 Python
Django视图、传参和forms验证操作
2020/07/15 Python
Python基于Faker假数据构造库
2020/11/30 Python
python 邮件检测工具mmpi的使用
2021/01/04 Python
Notino芬兰:购买香水和化妆品
2019/04/15 全球购物
PatPat阿根廷:妈妈们的购物平台
2019/05/30 全球购物
美国婴儿和儿童服装购物网站:PatPat
2020/10/01 全球购物
高中生职业生涯规划书
2014/02/24 职场文书
难忘的一天教学反思
2014/04/30 职场文书
个人查摆剖析材料
2014/10/16 职场文书
党支部培养考察意见
2015/06/02 职场文书
使用Nginx搭载rtmp直播服务器的方法
2021/10/16 Servers
mysqldump进行数据备份详解
2022/07/15 MySQL