Chinaunix首页 | 论坛 | 博客
  • 博客访问: 65098
  • 博文数量: 20
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 198
  • 用 户 组: 普通用户
  • 注册时间: 2013-03-31 17:15
文章分类

全部博文(20)

文章存档

2014年(1)

2013年(19)

我的朋友

分类: PHP

2013-04-01 18:02:03

示例:

点击(此处)折叠或打开

  1. // 进队操作
  2. $shmq = new SHMQueue();
  3. $data = 'test data';
  4. $shmq->enQueue($data);
  5. unset($shmq);
  6. // 出队操作
  7. $shmq = new SHMQueue();
  8. $data = $shmq->deQueue();
  9. unset($shmq);

点击(此处)折叠或打开

  1. <?php
  2. /**
  3. * 使用共享内存的PHP循环内存队列实现
  4. * 支持多进程, 支持各种数据类型的存储
  5. * 注: 完成入队或出队操作,尽快使用unset(), 以释放临界区
  6. *
  7. * @author wangbinandi@gmail.com
  8. * @created 2009-12-23
  9. */
  10. class SHMQueue
  11. {
  12.     private $maxQSize = 0; // 队列最大长度
  13.        
  14.     private $front = 0; // 队头指针
  15.     private $rear = 0; // 队尾指针
  16.        
  17.     private $blockSize = 256; // 块的大小(byte)
  18.     private $memSize = 25600; // 最大共享内存(byte)
  19.     private $shmId = 0;
  20.        
  21.     private $filePtr = './shmq.ptr';
  22.        
  23.     private $semId = 0;
  24.     public function __construct()
  25.     {
  26.         $shmkey = ftok(__FILE__, 't');
  27.            
  28.         $this->shmId = shmop_open($shmkey, "c", 0644, $this->memSize );
  29.         $this->maxQSize = $this->memSize / $this->blockSize;
  30.            
  31.          // 申請一个信号量
  32.         $this->semId = sem_get($shmkey, 1);
  33.         sem_acquire($this->semId); // 申请进入临界区
  34.            
  35.         $this->init();
  36.     }
  37.        
  38.     private function init()
  39.     {
  40.         if ( file_exists($this->filePtr) ){
  41.             $contents = file_get_contents($this->filePtr);
  42.             $data = explode( '|', $contents );
  43.             if ( isset($data[0]) && isset($data[1])){
  44.                 $this->front = (int)$data[0];
  45.                 $this->rear = (int)$data[1];
  46.             }
  47.         }
  48.     }
  49.        
  50.     public function getLength()
  51.     {
  52.         return (($this->rear - $this->front + $this->memSize) % ($this->memSize) )/$this->blockSize;
  53.     }
  54.        
  55.     public function enQueue( $value )
  56.     {
  57.         if ( $this->ptrInc($this->rear) == $this->front ){ // 队满
  58.             return false;
  59.         }
  60.            
  61.         $data = $this->encode($value);
  62.         shmop_write($this->shmId, $data, $this->rear );
  63.         $this->rear = $this->ptrInc($this->rear);
  64.         return true;
  65.     }
  66.            
  67.     public function deQueue()
  68.     {
  69.         if ( $this->front == $this->rear ){ // 队空
  70.             return false;
  71.         }
  72.         $value = shmop_read($this->shmId, $this->front, $this->blockSize-1);
  73.         $this->front = $this->ptrInc($this->front);
  74.         return $this->decode($value);
  75.     }
  76.        
  77.     private function ptrInc( $ptr )
  78.     {
  79.         return ($ptr + $this->blockSize) % ($this->memSize);
  80.     }
  81.        
  82.     private function encode( $value )
  83.     {
  84.         $data = serialize($value) . "__eof";
  85.         if ( strlen($data) > $this->blockSize -1 ){
  86.             throw new Exception(strlen($data)." is overload block size!");
  87.         }
  88.         return $data;
  89.     }
  90.        
  91.     private function decode( $value )
  92.     {
  93.         $data = explode("__eof", $value);
  94.         return unserialize($data[0]);
  95.     }
  96.        
  97.     public function __destruct()
  98.     {
  99.         $data = $this->front . '|' . $this->rear;
  100.         file_put_contents($this->filePtr, $data);
  101.            
  102.         sem_release($this->semId); // 出临界区, 释放信号量
  103.     }
  104. }

阅读(1359) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~