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
一篇不错的PHP基础学习笔记
Mar 18 PHP
php处理json时中文问题的解决方法
Apr 12 PHP
PHP中文分词的简单实现代码分享
Jul 17 PHP
php简单浏览目录内容的实现代码
Jun 07 PHP
深入解析fsockopen与pfsockopen的区别
Jul 05 PHP
PHP Web木马扫描器代码分享
Sep 06 PHP
PHP+swoole实现简单多人在线聊天群发
Jan 19 PHP
Apache无法自动跳转却显示目录的解决方法
Nov 30 PHP
PHP简单实现二维数组的矩阵转置操作示例
Nov 24 PHP
PHP7.1实现的AES与RSA加密操作示例
Jun 15 PHP
ThinkPHP6.0如何利用自定义验证规则规范的实现登陆
Dec 16 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 session会话的安全性分析
2011/09/08 PHP
php获取文件内容最后一行示例
2014/01/09 PHP
ThinkPHP之M方法实例详解
2014/06/20 PHP
PHP编程中的__clone()方法使用详解
2015/11/27 PHP
给WordPress中的留言加上楼层号的PHP代码实例
2015/12/14 PHP
PHP实现的数独求解问题示例
2017/04/18 PHP
实例分析基于PHP微信网页获取用户信息
2017/11/24 PHP
ThinkPHP5 的简单搭建和使用详解
2018/11/15 PHP
jQuery 学习第五课 Ajax 使用说明
2010/05/17 Javascript
深入理解JQuery keyUp和keyDown的区别
2013/12/12 Javascript
javascript委托(Delegate)blur和focus用法实例分析
2015/05/26 Javascript
跟我学习javascript的prototype,getPrototypeOf和__proto__
2015/11/17 Javascript
AngularJS实现元素显示和隐藏的几个案例
2015/12/09 Javascript
Angular6 写一个简单的Select组件示例
2018/08/20 Javascript
详解如何使用koa实现socket.io官网的例子
2018/11/04 Javascript
el-input 标签中密码的显示和隐藏功能的实例代码
2019/07/19 Javascript
layui点击数据表格添加或删除一行的例子
2019/09/12 Javascript
[34:56]Ti4冒泡赛LGD vs Liquid 1
2014/07/14 DOTA
[01:06:30]DOTA2-DPC中国联赛定级赛 Phoenix vs DLG BO3第二场 1月9日
2021/03/11 DOTA
Python2.x版本中cmp()方法的使用教程
2015/05/14 Python
Python中处理字符串的相关的len()方法的使用简介
2015/05/19 Python
python字符串中匹配数字的正则表达式
2019/07/03 Python
Pytoch之torchvision.transforms图像变换实例
2019/12/30 Python
python实现跨excel sheet复制代码实例
2020/03/03 Python
使用darknet框架的imagenet数据分类预训练操作
2020/07/07 Python
纯CSS改变webkit内核浏览器的滚动条样式
2014/04/17 HTML / CSS
CSS3实现可翻转的hover效果
2018/05/23 HTML / CSS
HTML5拖放API实现拖放排序的实例代码
2017/05/11 HTML / CSS
丽笙酒店官方网站:Radisson Hotels
2019/05/07 全球购物
澳大利亚优惠网站:Deals.com.au
2019/07/02 全球购物
加拿大领先的时尚和体育零售商:Sporting Life
2019/12/15 全球购物
消防志愿者活动方案
2014/08/23 职场文书
关于运动会的广播稿(10篇)
2014/09/12 职场文书
小学六一儿童节活动开幕词
2016/03/04 职场文书
Vue3.0写自定义指令的简单步骤记录
2021/06/27 Vue.js
MySQL 十大常用字符串函数详解
2021/06/30 MySQL