note 103285 added to function.shm-attach
| From: | nathanbruer at gmail dot com | Date: | Tue, 05 Apr 2011 20:21:21 +0000 |
| Subject: | note 103285 added to function.shm-attach | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-178529@lists.php.net to get a copy of this message | ||
I was playing around with these functions and made a class in the process. This will of course be
slower than accessing a variable locally, but gives the ability to store variables in a shared
environment and gives many running scripts the understanding that it should access them from the
shared area. This should also auto destroy the shared memory area once no more scripts have a link
to the data (when all scripts use this class).
<?php
class SharedMemory{
private $nameToKey = array();
private $key;
private $id;
function __construct($key = null){
if($key === null){
$tmp = tempnam('/tmp', 'PHP');
$this->key = ftok($tmp, 'a');
$this->id = shm_attach($this->key);
$this->nameToKey[] = '';
$this->nameToKey[] = '';
$this->updateMemoryVarList();
shm_put_var($this->id, 1, 1);
}else{
$this->key = $key;
$this->id = sem_get($this->key);
$this->refreshMemoryVarList();
shm_put_var($this->id, 1, shm_get_var($this->id, 1) + 1);
}
if(!$this->id)
die('Unable to create shared memory segment');
}
function __sleep(){
shm_detach($this->id);
}
function __destruct(){
if(shm_get_var($this->id, 1) == 1){
// I am the last listener so kill shared memory space
$this->remove();
}else{
shm_detach($this->id);
shm_put_var($this->id, 1, shm_get_var($this->id, 1) - 1);
}
}
function __wakeup(){
$this->id = sem_get($this->key);
shm_attach($this->id);
$this->refreshMemoryVarList();
shm_put_var($this->id, 1, shm_get_var($this->id, 1) + 1);
}
function getKey(){
return $this->key;
}
function remove(){
shm_remove($this->id);
}
function refreshMemoryVarList(){
$this->nameToKey = shm_get_var($this->id, 0);
}
function updateMemoryVarList(){
shm_put_var($this->id, 0, $this->nameToKey);
}
function __get($var){
if(!in_array($var, $this->nameToKey)){
$this->refreshMemoryVarList();
}
return shm_get_var($this->id, array_search($var, $this->nameToKey));
}
function __set($var, $val){
if(!in_array($var, $this->nameToKey)){
$this->refreshMemoryVarList();
$this->nameToKey[] = $var;
$this->updateMemoryVarList();
}
shm_put_var($this->id, array_search($var, $this->nameToKey), $val);
}
}
// Example
$sharedMem = new SharedMemory();
$pid = pcntl_fork();
if($pid){
//parent
sleep(1);
echo "Parent Says: " . $sharedMem->a . "\n";
echo "Parent Changed to 0\n";
$sharedMem->a = 0;
//Parent just changed it to 0
echo "Parent Says: " . $sharedMem->a . "\n";
sleep(2);
// Parent think's it's 0, but child has changed it to 1
echo "Parent Says: " . $sharedMem->a . "\n";
}else{
//child
$sharedMem->a = 2;
echo "Child Changed to 2\n";
// Should be 2 as child just set it to 2
echo "Child Says: " . $sharedMem->a . "\n";
sleep(2);
// Child think's it's 2, but the parent set it to 0.
echo "Child Says: " . $sharedMem->a . "\n";
echo "Child Added 1\n";
$sharedMem->a++;
echo "Child Says: " . $sharedMem->a . "\n";
}
?>
----
Server IP: 192.41.42.26
Probable Submitter: 12.71.233.34
----
Manual Page -- http://www.php.net/manual/en/function.shm-attach.php
Edit -- https://master.php.net/note/edit/103285
Del: integrated -- https://master.php.net/note/delete/103285/integrated
Del: useless -- https://master.php.net/note/delete/103285/useless
Del: bad code -- https://master.php.net/note/delete/103285/bad+code
Del: spam -- https://master.php.net/note/delete/103285/spam
Del: non-english -- https://master.php.net/note/delete/103285/non-english
Del: in docs -- https://master.php.net/note/delete/103285/in+docs
Del: other reasons-- https://master.php.net/note/delete/103285
Reject -- https://master.php.net/note/reject/103285
Search -- https://master.php.net/manage/user-notes.php