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 相关文章推荐
深入PHP5中的魔术方法详解
Jun 17 PHP
编写Smarty插件在模板中直接加载数据的详细介绍
Jun 26 PHP
从PHP $_SERVER相关参数判断是否支持Rewrite模块
Sep 26 PHP
PHP实现的多彩标签效果代码分享
Aug 21 PHP
php生成不重复随机数、数组的4种方法分享
Mar 30 PHP
WIFI万能钥匙密码查询接口实例
Sep 28 PHP
PHP多维数组转一维数组的简单实现方法
Dec 23 PHP
PHP自带方法验证邮箱是否存在
Feb 01 PHP
浅析php设计模式之数据对象映射模式
Mar 03 PHP
PHP会话操作之cookie用法分析
Sep 28 PHP
php使用json_decode后数字对象转换成了科学计数法的解决方法
Feb 20 PHP
Thinkphp5.0 框架使用模型Model添加、更新、删除数据操作详解
Oct 11 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
discuz authcode 经典php加密解密函数解析
2020/07/12 PHP
php+ajax实现无刷新动态加载数据技术
2015/04/28 PHP
PHP针对redis常用操作实例详解
2019/08/17 PHP
Thinkphp 3.2框架使用Redis的方法详解
2019/10/24 PHP
linux mint下安装phpstorm2020包括JDK部分的教程详解
2020/09/17 PHP
Script的加载方法小结
2011/01/12 Javascript
High Performance JavaScript(高性能JavaScript)读书笔记分析
2011/05/05 Javascript
JavaScript中__proto__与prototype的关系深入理解
2012/12/04 Javascript
JS小功能(offsetLeft实现图片滚动效果)实例代码
2013/11/28 Javascript
jQuery对下拉框,单选框,多选框的操作
2014/02/21 Javascript
文本框水印提示效果的简单实现代码
2014/02/22 Javascript
AngularJS中的模块详解
2015/01/29 Javascript
JavaScript实现控制打开文件另存为对话框的方法
2015/04/17 Javascript
使用grunt合并压缩js和css文件的方法
2017/03/02 Javascript
Vue.2.0.5过渡效果使用技巧
2017/03/16 Javascript
vue中使用ueditor富文本编辑器
2018/02/08 Javascript
解决Vue+Element ui开发中碰到的IE问题
2018/09/03 Javascript
JavaScript实现的九种排序算法
2019/03/04 Javascript
解决vue项目input输入框双向绑定数据不实时生效问题
2020/08/05 Javascript
浅谈javascript事件环微任务和宏任务队列原理
2020/09/12 Javascript
JSON 入门教程基础篇 json入门学习笔记
2020/09/22 Javascript
一篇文章让你搞懂JavaScript 原型和原型链
2020/11/23 Javascript
[02:22:36]《加油!DOTA》总决赛
2014/09/19 DOTA
用Python实现KNN分类算法
2017/12/22 Python
python爬虫中get和post方法介绍以及cookie作用
2018/02/08 Python
Python读取Pickle文件信息并计算与当前时间间隔的方法分析
2019/01/30 Python
python实现图书借阅系统
2019/02/20 Python
序列化Python对象的方法
2020/08/01 Python
python asyncio 协程库的使用
2021/01/21 Python
html5/css3响应式页面开发总结
2018/10/16 HTML / CSS
HTML5 canvas 瀑布流文字效果的示例代码
2018/01/31 HTML / CSS
销售人员自我评价
2014/02/01 职场文书
写自荐信的注意事项
2014/03/09 职场文书
中学生国旗下讲话稿
2014/04/26 职场文书
社区文艺活动方案
2014/08/19 职场文书
vue里使用create, mounted调用方法
2022/04/26 Vue.js