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 array_flip() 删除数组重复元素
Jan 14 PHP
php插入中文到sqlserver 2008里出现乱码的解决办法分享
Jul 19 PHP
基于PHP5魔术常量与魔术方法的详解
Jun 13 PHP
PHP之APC缓存详细介绍 apc模块安装
Jan 13 PHP
PHP实现获取图片颜色值的方法
Jul 11 PHP
Thinkphp调用Image类生成缩略图的方法
Mar 07 PHP
PHP实现递归复制整个文件夹的类实例
Aug 03 PHP
WordPress迁移时一些常见问题的解决方法整理
Nov 24 PHP
解析WordPress中控制用户登陆和判断用户登陆的PHP函数
Mar 01 PHP
php中使用GD库做验证码
Mar 31 PHP
PHP中include和require的区别实例分析
May 07 PHP
PHP全局使用Laravel辅助函数dd
Dec 26 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文本操作类
2006/11/25 PHP
php目录管理函数小结
2008/09/10 PHP
PHP生成迅雷、快车、旋风等软件的下载链接代码实例
2014/05/12 PHP
php版微信公众平台实现预约提交后发送email的方法
2016/09/26 PHP
php对xml文件的增删改查操作实现方法分析
2017/05/19 PHP
javascript中attribute和property的区别详解
2014/06/05 Javascript
基于JS实现回到页面顶部的五种写法(从实现到增强)
2016/09/03 Javascript
JS数字千分位格式化实现方法总结
2016/12/16 Javascript
Vue.js路由vue-router使用方法详解
2017/03/20 Javascript
nodejs mysql 实现分页的方法
2017/06/06 NodeJs
文本溢出插件jquery.dotdotdot.js使用方法详解
2017/06/22 jQuery
webpack写jquery插件的环境配置
2017/12/21 jQuery
element-ui 关于获取select 的label值方法
2018/08/24 Javascript
Puppet的一些技巧
2018/09/17 Javascript
小程序hover-class点击态效果实现
2019/02/26 Javascript
Vuejs学习笔记之使用指令v-model完成表单的数据双向绑定
2019/04/29 Javascript
Vue-cli3多页面配置详解
2020/03/22 Javascript
javascript实现搜索筛选功能实例代码
2020/11/12 Javascript
python中的五种异常处理机制介绍
2014/09/02 Python
Python 中的 else详解
2016/04/23 Python
老生常谈python的私有公有属性(必看篇)
2017/06/09 Python
实例讲解python中的协程
2018/10/08 Python
python time.sleep()是睡眠线程还是进程
2019/07/09 Python
python GUI库图形界面开发之PyQt5开发环境配置与基础使用
2020/02/25 Python
Python pip安装模块提示错误解决方案
2020/05/22 Python
Oroton中国官网:澳洲知名奢侈配饰品牌
2017/03/26 全球购物
英智兴达软件测试笔试题
2016/10/12 面试题
党员批评与自我批评
2014/02/12 职场文书
校庆活动方案
2014/03/31 职场文书
《翻越远方的大山》教学反思
2014/04/13 职场文书
城管大队整治方案
2014/05/06 职场文书
党员违纪检讨书怎么写
2014/11/01 职场文书
2014年全国法制宣传日宣传活动方案
2014/11/02 职场文书
房产公证书
2015/01/23 职场文书
服务员岗位职责范本
2015/04/09 职场文书
2016优秀护士求职自荐信
2016/01/28 职场文书