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加MYSQL服务器
Oct 09 PHP
搜索引擎技术核心揭密
Oct 09 PHP
不用数据库的多用户文件自由上传投票系统(2)
Oct 09 PHP
php array_map()数组函数使用说明
Jul 12 PHP
PHP变量内存分配问题记录整理
Nov 27 PHP
php json转换成数组形式代码分享
Nov 10 PHP
PHP中创建图像并绘制文字的例子
Nov 19 PHP
php多重接口的实现方法
Jun 20 PHP
深入理解PHP内核(一)
Nov 10 PHP
PHP验证码生成原理和实现
Jan 24 PHP
php判断是否连接上网络的方法实例详解
Dec 14 PHP
PHP基础之输出缓冲区基本概念、原理分析
Jun 19 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
smarty静态实验表明,网络上是错的~呵呵
2006/11/25 PHP
php实现数组纵向转横向并过滤重复值的方法分析
2017/05/29 PHP
ThinkPHP+EasyUI之ComboTree中的会计科目树形菜单实现方法
2017/06/09 PHP
php定期拉取数据对比方法实例
2019/09/22 PHP
ajax不执行success回调而是执行了error回调
2012/12/10 Javascript
script的async属性以非阻塞的模式加载脚本
2013/01/15 Javascript
Javascript中this的用法详解
2014/09/22 Javascript
javascript解析json实例详解
2014/11/05 Javascript
AngularJS内置指令
2015/02/04 Javascript
javascript HTML5 canvas实现打砖块游戏
2020/06/18 Javascript
微信小程序 框架详解及实例应用
2016/09/26 Javascript
js实现颜色阶梯渐变效果(Gradient算法)
2017/03/21 Javascript
详解使用angular的HttpClient搭配rxjs
2017/09/01 Javascript
JS解析后台返回的JSON格式数据实例
2018/08/06 Javascript
实例讲解JavaScript截取字符串
2018/11/30 Javascript
Vue开发之封装分页组件与使用示例
2019/04/25 Javascript
基于vue实现圆形菜单栏组件
2019/07/05 Javascript
JavaScript实现好看的跟随彩色气泡效果
2020/02/06 Javascript
微信小程序input抖动问题的修复方法
2021/03/03 Javascript
浅谈Python中带_的变量或函数命名
2017/12/04 Python
Python读写zip压缩文件的方法
2018/08/29 Python
Python3 使用pillow库生成随机验证码
2019/08/26 Python
python return逻辑判断表达式实现解析
2019/12/02 Python
Python 获取命令行参数内容及参数个数的实例
2019/12/20 Python
TENSORFLOW变量作用域(VARIABLE SCOPE)
2020/01/10 Python
Python3之外部文件调用Django程序操作model等文件实现方式
2020/04/07 Python
Staples美国官方网站:办公用品一站式采购
2016/07/28 全球购物
初中生学习的自我评价
2013/11/14 职场文书
高中毕业生个人自我鉴定
2013/11/24 职场文书
学生安全责任书
2014/04/15 职场文书
建筑安全标语
2014/06/07 职场文书
村党支部对照检查材料思想汇报
2014/09/28 职场文书
杭州黄龙洞导游词
2015/02/10 职场文书
当幸福来敲门英文观后感
2015/06/01 职场文书
利用 SQL Server 过滤索引提高查询语句的性能分析
2021/07/15 SQL Server
python数字类型和占位符详情
2022/03/13 Python