|
/**
* PHP loop Memory queue implementation using shared memory
* Support multi-process, support a variety of data types of storage
* Note: Complete the queue or team operation and use Unset () as soon as possible to release the critical section
*
* @author wangbinandi@gmail.com
* @created 2009-12-23
*/
Class Shmqueue
{
Private $maxQSize = 0; Maximum Queue Length
Private $front = 0; Team Head pointer
Private $rear = 0; Team Tail Hands
Private $blockSize = 256; Size of block (byte)
Private $memSize = 25600; Maximum shared memory (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;
A semaphore.
$this->semid = Sem_get ($shmkey, 1);
Sem_acquire ($this->semid); Apply for entry into the critical section
$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) {//Team full
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) {//Team empty
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); Out of the critical zone, releasing the semaphore
}
}
/*
Incoming team operation
$SHMQ = new Shmqueue ();
$data = ' test data ';
$SHMQ->enqueue ($data);
Unset ($SHMQ);
Out of team operation
$SHMQ = new Shmqueue ();
$data = $shmq->dequeue ();
Unset ($SHMQ);
*/
?>
|