A5下载文章资讯

分类分类

PHP共享内存用法实例分析

2016-02-12 22:20作者:fang

本文实例讲述了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程序设计有所帮助。

展开全部

相关

说两句网友评论
    我要跟贴
    取消