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 之入门篇
Dec 04 PHP
php Xdebug的安装与使用详解
Jun 20 PHP
ThinkPHP CURD方法之data方法详解
Jun 18 PHP
PHP制作3D扇形统计图以及对图片进行缩放操作实例
Oct 23 PHP
CI配置多数据库访问的方法
Mar 28 PHP
php实现URL加密解密的方法
Nov 17 PHP
使用PHPMailer发送邮件实例
Feb 15 PHP
浅谈PHP无限极分类原理
Mar 14 PHP
Linux下安装Memcached服务器和客户端与PHP使用示例
Apr 15 PHP
PHP+Redis开发的书签案例实战详解
Jul 09 PHP
PHP扩展类型及安装方式解析
Apr 27 PHP
THINKPHP-Apache服务器中使用Alias虚拟目录URL重写 隐藏index.php
Mar 09 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
火车头discuz6.1 完美采集的php接口文件
2009/09/13 PHP
PHP Session变量不能传送到下一页的解决方法
2009/11/27 PHP
PHP similar_text 字符串的相似性比较函数
2010/05/26 PHP
PHP setTime 设置当前时间的代码
2012/08/27 PHP
PHP cookie与session会话基本用法实例分析
2019/11/18 PHP
如何实现修改密码时密码框显示保存到cookie的密码
2013/12/10 Javascript
jQuery实现有动画淡出效果的二级折叠菜单代码
2015/10/17 Javascript
javascript中的后退和刷新实现方法
2016/11/10 Javascript
JavaScript实现倒计时跳转页面功能【实用】
2016/12/13 Javascript
jQuery Ajax 实现在html页面实时显示用户登录状态
2016/12/30 Javascript
前端框架学习总结之Angular、React与Vue的比较详解
2017/03/14 Javascript
jQuery.Form实现Ajax上传文件同时设置headers的方法
2017/06/26 jQuery
用JS编写一个函数,返回数组中重复出现过的元素(实例)
2017/09/14 Javascript
vue2.0 路由不显示router-view的解决方法
2018/03/06 Javascript
原生JS实现的自动轮播图功能详解
2018/12/28 Javascript
elementUi vue el-radio 监听选中变化的实例代码
2019/06/28 Javascript
详解mpvue实现对苹果X安全区域的适配
2019/07/31 Javascript
javascript实现摄像头拍照预览
2019/09/30 Javascript
用JS实现一个简单的打砖块游戏
2019/12/11 Javascript
JS使用setInterval计时器实现挑战10秒
2020/11/08 Javascript
[39:53]完美世界DOTA2联赛PWL S2 LBZS vs Forest 第一场 11.19
2020/11/19 DOTA
Python collections模块实例讲解
2014/04/07 Python
python新手经常遇到的17个错误分析
2014/07/30 Python
Python与Redis的连接教程
2015/04/22 Python
2018年Python值得关注的开源库、工具和开发者(总结篇)
2018/01/04 Python
弄懂这56个Python使用技巧(轻松掌握Python高效开发)
2019/09/18 Python
关于Python中定制类的比较运算实例
2019/12/19 Python
如何在windows下安装配置python工具Ulipad
2020/10/27 Python
使用postMessage让 iframe自适应高度的方法示例
2019/10/08 HTML / CSS
小橄榄树:Le Petit Olivier
2018/04/23 全球购物
大三在校生电子商务求职信
2013/10/29 职场文书
廉洁使者实施方案
2014/03/29 职场文书
彩色的翅膀教学反思
2014/04/25 职场文书
小学安全教育主题班会
2015/08/12 职场文书
JavaScript实现简单图片切换
2021/04/29 Javascript
java实现web实时消息推送的七种方案
2022/07/23 Java/Android