共享内存主要用于进程间通信

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 命令可以删除

参考:http://www.laruence.com/2008/04/21/101.html

    http://www.yuansir-web.com/2012/09/22/php

php 共享内存的更多相关文章

  1. Linux 共享内存详解一

    共享内存段被多个进程附加的时候,如果不是所有进程都已经调用shmdt,那么删除该共享内存段时,会出现一个临时的不完整的共享内存段(key值是0),无法彻底删除.只有当所有进程都调用shmdt,这个临时 ...

  2. PHP进程通信基础——信号量+共享内存通信

    PHP进程通信基础--信号量+共享内存通信 由于进程之间谁先执行并不确定,这取决于内核的进程调度算法,其中比较复杂.由此有可能多进程在相同的时间内同时访问共享内存,从而造成不可预料的错误.信号量这个名 ...

  3. C++ 共享内存 函数封装

    #pragma once #include <string> #include <wtypes.h> #include <map> using namespace ...

  4. Linux学习笔记(14)-进程通信|共享内存

    在Linux中,共享内存是允许两个不相关的进程访问同一个逻辑内存的进程间通信方法,是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式. 不同进程之间共享的内存通常安排为同一段物理内存.进程可 ...

  5. linux 共享内存 shmat,shmget,shmdt,shmctl

    shmget int shmget(key_t key, size_t size, int flag);//开辟一段共享内存 key_t key :标识符的规则() size_t size :共享内存 ...

  6. Linux进程间通信(六):共享内存 shmget()、shmat()、shmdt()、shmctl()

    下面将讲解进程间通信的另一种方式,使用共享内存. 一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式 ...

  7. linux后台查看共享内存和消息队列的命令

    ipcs ipcs -q : 显示所有的消息队列 ipcs -qt : 显示消息队列的创建时间,发送和接收最后一条消息的时间 ipcs -qp: 显示往消息队列中放消息和从消息队列中取消息的进程ID ...

  8. c++共享内存(转载)

    对于连个不同的进程之间的通信,共享内存是一种比较好的方式,一个进程把数据发送到共享内存中, 另一个进程可以读取改数据,简单记录一下代码 #define BUF_SIZE 256 TCHAR szNam ...

  9. OpenMP共享内存并行编程详解

    实验平台:win7, VS2010 1. 介绍 平行计算机可以简单分为共享内存和分布式内存,共享内存就是多个核心共享一个内存,目前的PC就是这类(不管是只有一个多核CPU还是可以插多个CPU,它们都有 ...

  10. android共享内存

    在android下不能通过shm_open使用共享内存. 网上有好多关于android下使用Ashmem实现共享内存的,但经过尝试该方法可以mmap出内存,但是和另一个进程没有实现共享. 具体的使用方 ...

随机推荐

  1. 5分钟实现Android中更换头像功能

    写在前面:更换头像这个功能在用户界面几乎是100%出现的.通过拍摄照片或者调用图库中的图片,并且进行剪裁,来进行头像的设置.功能相关截图如下: 下面我们直接看看完整代码吧: 1 2 3 4 5 6 7 ...

  2. Page cache和Buffer cache[转1]

    http://www.cnblogs.com/mydomain/archive/2013/02/24/2924707.html Page cache实际上是针对文件系统的,是文件的缓存,在文件层面上的 ...

  3. pouchdb sync

    PouchDB and CouchDB were designed for one main purpose: sync. Jason Smith has a great quote about th ...

  4. 安卓模拟器安装apk,上网

    1.首先找到安装安卓模拟器的文件夹: 2.目录:D:\Java\Android-all\platform-tools 3.运行cmd命令:adb install D:\Java\Android-all ...

  5. redis 服务访问密码设定

    1. 更改redis.conf配置 # requirepass foobared 去掉注释,foobared改为 自己的password , 我测试的时候用的是 redis-password 2.启动 ...

  6. scala vs java 相同点和差异

    本贴是我摘抄自国外网站,用作备忘,也作为分享! Similarities between Scala and Java Following are some of the major similari ...

  7. (转)[SQL Server] 动态sql给变量赋值(或返回值给变量)

    本文转载自:http://blog.csdn.net/xiaoxu0123/article/details/5684680 [SQL Server] 动态sql给变量赋值(或返回值给变量) decla ...

  8. 【多线程】Future和FutureTask以及CompletionService

    Future接口 此接口主要用于: 代表异步计算的执行结果: 用于可取消的task:(比使用interrupt实现取消要方便 ) FutureTask类 FutureTask是Future的一个实现类 ...

  9. bzoj1173: [Balkan2007]Point

    Description 给出N个三维空间上的点. 问有多少条直线,这些直线上至少有三个点. Input 第一行给出数字N,N在[4,1000] 下面N行,每行三个数字,用于描述点的坐标,其值在[-10 ...

  10. android学习笔记39——使用原始资源

    原始资源 android中没有专门提供管理支持的类型文件,都被称为原始资源.例如:声音资源... android原始资源存放位置: 1.res/raw,android SDK会处理该目录下的原始资源, ...