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 select,radio和checkbox默认选择的实现方法
May 15 PHP
php dirname(__FILE__) 获取当前文件的绝对路径
Jun 28 PHP
PHP header()函数使用详细(301、404等错误设置)
Apr 17 PHP
php批量更改数据库表前缀实现方法
Oct 26 PHP
php中的PHP_EOL换行符详细解析
Oct 26 PHP
PHP实现使用优酷土豆视频地址获取swf播放器分享地址
Jun 05 PHP
PHP读取RSS(Feed)简单实例
Jun 12 PHP
PHP实现加密的几种方式介绍
Feb 22 PHP
Yii视图CGridView实现操作按钮定义地址示例
Jul 14 PHP
Yii框架中jquery表单验证插件用法示例
Oct 18 PHP
thinkphp实现把数据库中的列的值存到下拉框中的方法
Jan 20 PHP
php中的钩子理解及应用实例分析
Aug 30 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
Windows2003 下 MySQL 数据库每天自动备份
2006/12/21 PHP
PHP中开发XML应用程序之基础篇 添加节点 删除节点 查询节点 查询节
2010/07/09 PHP
浅析php中三个等号(===)和两个等号(==)的区别
2013/08/06 PHP
PHP中提问频率最高的11个面试题和答案
2014/09/02 PHP
php单例模式示例分享
2015/02/12 PHP
php查询相似度最高的字符串的方法
2015/03/12 PHP
PHP开发中AJAX技术的简单应用
2015/12/11 PHP
详解Yii2.0 rules验证规则集合
2017/03/21 PHP
PHP实现数组根据某个单元字段排序操作示例
2018/08/01 PHP
List Installed Hot Fixes
2007/06/12 Javascript
JavaScript 函数式编程的原理
2009/10/16 Javascript
Javascript 自适应高度的Tab选项卡
2011/04/05 Javascript
jquery获取子节点和父节点的示例代码
2013/09/10 Javascript
jquery序列化form表单使用ajax提交后处理返回的json数据
2014/03/03 Javascript
无刷新上传文件并返回自定义值
2015/06/11 Javascript
盘点javascript 正则表达式中 中括号的【坑】
2016/03/16 Javascript
在JavaScript中模拟类(class)及类的继承关系
2016/05/20 Javascript
jquery 动态合并单元格的实现方法
2016/08/26 Javascript
jQuery实现扑克正反面翻牌效果
2017/03/10 Javascript
javascript数组定义的几种方法
2017/10/06 Javascript
Nodejs + Websocket 指定发送及群聊的实现
2020/01/09 NodeJs
Js数组扁平化实现方法代码总汇
2020/11/11 Javascript
python删除指定类型(或非指定)的文件实例详解
2015/07/06 Python
Python3.5多进程原理与用法实例分析
2019/04/05 Python
Python字符串格式化输出代码实例
2019/11/22 Python
Python 实现日志同时输出到屏幕和文件
2020/02/19 Python
Python+Django+MySQL实现基于Web版的增删改查的示例代码
2020/05/13 Python
在线服装零售商:SheIn
2016/07/22 全球购物
国际奢侈品品牌童装购物网站:Designer Childrenswear
2019/05/08 全球购物
安全责任书范本
2014/04/15 职场文书
基层党员公开承诺书
2014/05/29 职场文书
医院护士工作检讨书
2014/10/26 职场文书
交通事故一次性赔偿协议书范本
2014/11/02 职场文书
邮政营业员岗位职责
2015/04/14 职场文书
2015年留守儿童工作总结
2015/05/22 职场文书
详解JAVA的控制语句
2021/11/11 Java/Android