Basic usage

Example #1 Shared Memory Operations Overview

<?php
   
// Create 100 byte shared memory block with system id of 0xff3
$shm_id shmop_open(0xff3"c"0644100);
if (!
$shm_id) {
    echo 
"Couldn't create shared memory segment\n";
}

// Get shared memory block's size
$shm_size shmop_size($shm_id);
echo 
"SHM Block Size: " $shm_size " has been created.\n";

// Lets write a test string into shared memory
$shm_bytes_written shmop_write($shm_id"my shared memory block"0);
if (
$shm_bytes_written != strlen("my shared memory block")) {
    echo 
"Couldn't write the entire length of data\n";
}

// Now lets read the string back
$my_string shmop_read($shm_id0$shm_size);
if (!
$my_string) {
    echo 
"Couldn't read from shared memory block\n";
}
echo 
"The data inside shared memory was: " $my_string "\n";

//Now lets delete the block and close the shared memory segment
if (!shmop_delete($shm_id)) {
    echo 
"Couldn't mark shared memory block for deletion.";
}
shmop_close($shm_id);
   
?>

Коментарии

Автор:
Simple class for SHMOP implementation.

# Warning #

You can write/read only one direction. If you try read and write at the same time you get corrupt data. (Its works like STD in/out)
If you need bi-directional communication create 2 instance of shmop class.
Don't try attach more than one readers or writers for some shmid, you get corrupt data. This class use kludged spinlocks for improve speed, and not real atomic operations. You can add semaphore with flock, but it very slow. (~x3)

Benchmark:

Reads per sec: 6316 Data size per sec: 6.17 gb

<?php
########################
# shmopwriter.php
########################

$blockSize 1024 1024 100;
$data random_bytes($blockSize);

try
{
   
$shm = new SHMOP('shmopwriter.php''c'644$blockSize);

    while(
1)
    {
        if(!
$shm->canWrite())
            continue;

       
$shm->write($data);
    }

   
$shm->close();

} catch (
Exception $e) {
     echo 
'Error: '$e->getMessage(), PHP_EOL;
     exit;
}

########################

########################
# shmopreader.php
########################

$blockSize 1024 1024 100;
$shm = new SHMOP('shmopwriter.php''c'644$blockSize);
$readsMT 0;
$readsPS 0;

while(!
$shm->eof())
{
   
$times microtime(true);

    if((
$data $shm->read()) === false)
        continue;

   
$readsPS++;
   
$readsMT += round(((microtime(true) - $times ) * 1000), 3);
   
    if(
$readsMT 1000)
    {
        echo 
'Reads per sec: '$readsPS' Data size per sec: 'convert($blockSize $readsPS), PHP_EOL;
       
$readsPS 0;
       
$readsMT 0;
    }
}

function 
convert($size)
{
   
$unit=array('b','kb','mb','gb','tb','pb');
    return @
round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
}
########################

########################
# shmop.class.php
########################

class SHMOP
{
    private 
$shmId;
    private 
$shmHeaderSize;
    private 
$shmHeaderOffset;
    private 
$shmBlockSize;
    private 
$shmMaxBlockSize;

    function 
__construct(string $pathnamestring $flagsint $modeint $size)
    {
       
$this->shmHeaderSize strlen($size);
       
$this->shmHeaderOffset $this->shmHeaderSize 1;
       
$this->shmMaxBlockSize $size;
       
$this->shmBlockSize $size $this->shmHeaderOffset 1;

       
$this->shmId shmop_open(ftok($pathname's'), $flags$mode$this->shmBlockSize);

        if(!
$this->shmId)
            throw new 
Exception('shmop_open error');
    }
   
    function 
__destruct()
    {
        if(!
$this->shmId)
            return;

       
$this->close();
    }
   
    public function 
read()
    {
       
// Check SpinLock
       
if(shmop_read($this->shmId01) === "\0")
            return 
false;
       
       
// Get Header
       
$dataSize = (int)shmop_read($this->shmId1$this->shmHeaderSize);

       
$data shmop_read($this->shmId$this->shmHeaderOffset$dataSize);
       
// release spinlock
       
shmop_write($this->shmId"\0"0);
        return 
$data;
    }
   
    public function 
write(string $data)
    {
       
// Check SpinLock
       
if(shmop_read($this->shmId01) !== "\0")
            return 
false;

       
$dataSize strlen($data);

        if(
$dataSize 1)
            throw new 
Exception('dataSize < 1');
       
        if(
$dataSize $this->shmMaxBlockSize)
            throw new 
Exception('dataSize > shmMaxBlockSize: '$this->shmMaxBlockSize);
       
       
// pack very slow use kludge
       
$dataSize .= "\0";

       
// Write Header
       
shmop_write($this->shmId$dataSize1);
       
// Write Data
       
shmop_write($this->shmId$data$this->shmHeaderOffset);
       
// Write spinlock
       
shmop_write($this->shmId"\1"0);
        return 
true;
    }

    public function 
eof()
    {
        return (
shmop_read($this->shmId01) === "\2") ? true false;
    }
   
    public function 
sendeof()
    {
       
// Check SpinLock
       
if(shmop_read($this->shmId01) !== "\0")
            return 
false;

       
shmop_write($this->shmId"\2"0);
        return 
true;
    }
   
    public function 
canWrite()
    {
       
// Check SpinLock
       
return (shmop_read($this->shmId01) === "\0") ? true false;
    }
   
    public function 
close()
    {
        return @
shmop_close($this->shmId);
    }

    private function 
delete()
    {
       
$del = @shmop_delete($this->shmId);

        if(
$del === false)
            return 
false;

        return @
shmop_close($this->shmId);
    }
}

?>
2018-01-08 16:27:16
http://php5.kiev.ua/manual/ru/shmop.examples-basic.html

    Поддержать сайт на родительском проекте КГБ