|
<? Php
/**
* Implemented using PHP cyclic memory queue with shared memory
* Supports multi-process storage and various data types
* Note: To release the critical section, use unset () as soon as possible to complete the team-up or team-out operations.
*
* @ Author wangbinandi@gmail.com
* @ Created 2009-12-23
*/
Class ShmQueue
{
Private $ maxQSize = 0; // maximum Queue Length
Private $ front = 0; // head pointer
Private $ rear = 0; // team end pointer
Private $ blockSize = 256; // block size (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;
// Apply? A semaphore
$ This-> semId = sem_get ($ shmkey, 1 );
Sem_acquire ($ this-> semId); // apply to enter 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) {// full team
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) {// empty team
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); // outputs the critical section and releases the semaphore.
}
}
/*
// Enter the team
$ Shmq = new ShmQueue ();
$ Data = 'test data ';
$ Shmq-> enQueue ($ data );
Unset ($ shmq );
// Team-out operations
$ Shmq = new ShmQueue ();
$ Data = $ shmq-> deQueue ();
Unset ($ shmq );
*/
?> |