4

I just started to use shared memory in PHP to do something. Here my code is.

 <?php
//limit the task to be forked
$task = 100;
$process_pool = array();
//allocate 1kb memory segment to store process_pool
$process_pool_key = ftok(__FILE__,chr(0));
$process_pool_shm = shmop_open($process_pool_key,'c',0644,1024);
$datas = array();
for($i = 1; $i<= $task; $i++) {
    $pid = pcntl_fork();
    if ($pid == -1) {
        die("Can't fork child process.");
    }
    if ($pid == 0) {
        $current_pid = getmypid();
        $process_pool_size = shmop_size($process_pool_shm);
        $process_pool = @unserialize(shmop_read($process_pool_shm,0,$process_pool_size));
        //store child process data into specific memory
        $child_data  = array('pid'=>$current_pid,"data"=>[rand(),'hello']);
        $child_key = ftok(__FILE__,chr($current_pid));
   }

        $size = 1024*1024; 
        $child_shm = shmop_open($child_key,'c',0644,$size);
        shmop_write($child_shm,serialize($child_data),0);
        exit(0);
    } else {
       $process_pool[$pid] = array($pid);
       shmop_write($process_pool_shm,serialize($process_pool),0);
   }
}
while(pcntl_waitpid(-1,$status) > 0);
//Read data from all child process
foreach($process_pool as $pid => $pid_info) {
    $tmp_key = ftok(__FILE__,chr($pid));
    $size= 1024*1024;
    $tmp_shm  = shmop_open($tmp_key,'a',0644,$size);
    $org_data = shmop_read($tmp_shm,0,$size);
    $child_data = @unserialize($org_data);
    if (empty($child_data)) {
        echo "$tmp_key\n";
    }
    shmop_delete($tmp_shm);
    shmop_close($tmp_shm);
    if (!empty($child_data)) {
        $datas[$pid] = $child_data;
    }
}
var_dump(count($datas));
//var_dump(count($process_pool));
//var_dump(count(array_keys($datas)));
//var_dump(count(array_keys($process_pool)));
foreach (array_keys($process_pool) as $p_key) {
    if (!in_array($p_key,array_keys($datas))) {
        echo $p_key."\n";
    }
}
shmop_delete($process_pool_shm);
shmop_close($process_pool_shm);

The code above spaws several child processes, which hold their own shared memory segments each other.Shared memory segments of child process are used to store data after it processed.And the parent process will collect the data from child process' shared memory segments after child process finished.

In my humble opinion, this code should run without any problems. But some unexpected problems spat randomly.

Sometimes it went well

/home/jhbian/pider/test/process/ReproduceProcessExample.php:60:
int(100)

Sometimes it cracked down

 PHP Warning:  shmop_open(): unable to attach or create shared memory segment 'Invalid argument' in /home/jhbian/pider/test/process/ReproduceProcessExample.php on line 29
PHP Stack trace:
PHP   1. {main}() /home/jhbian/pider/test/process/ReproduceProcessExample.php:0
PHP   2. shmop_open() /home/jhbian/pider/test/process/ReproduceProcessExample.php:29

Warning: shmop_open(): unable to attach or create shared memory segment 'Invalid argument' in /home/jhbian/pider/test/process/ReproduceProcessExample.php on line 29

Call Stack:
    0.0002     366568   1. {main}() /home/jhbian/pider/test/process/ReproduceProcessExample.php:0
    0.0738     367872   2. shmop_open() /home/jhbian/pider/test/process/ReproduceProcessExample.php:29

PHP Warning:  shmop_write() expects parameter 1 to be resource, boolean given in /home/jhbian/pider/test/process/ReproduceProcessExample.php on line 30
PHP Stack trace:
PHP   1. {main}() /home/jhbian/pider/test/process/ReproduceProcessExample.php:0
PHP   2. shmop_write() /home/jhbian/pider/test/process/ReproduceProcessExample.php:30

Warning: shmop_write() expects parameter 1 to be resource, boolean given in /home/jhbian/pider/test/process/ReproduceProcessExample.php on line 30

Call Stack:
    0.0002     366568   1. {main}() /home/jhbian/pider/test/process/ReproduceProcessExample.php:0
    0.0755     368192   2. shmop_write() /home/jhbian/pider/test/process/ReproduceProcessExample.php:30

PHP Warning:  shmop_read(): count is out of range in /home/jhbian/pider/test/process/ReproduceProcessExample.php on line 49
PHP Stack trace:
PHP   1. {main}() /home/jhbian/pider/test/process/ReproduceProcessExample.php:0
PHP   2. shmop_read() /home/jhbian/pider/test/process/ReproduceProcessExample.php:49

Warning: shmop_read(): count is out of range in /home/jhbian/pider/test/process/ReproduceProcessExample.php on line 49

Call Stack:
    0.0002     366568   1. {main}() /home/jhbian/pider/test/process/ReproduceProcessExample.php:0
    0.1350    1551336   2. shmop_read() /home/jhbian/pider/test/process/ReproduceProcessExample.php:49

104785
/home/jhbian/pider/test/process/ReproduceProcessExample.php:60:
int(99)
16896

Can anybody point out where the hinge is?

2
  • What environment are you running this code in? Web server? CLI? Other? Commented Oct 20, 2017 at 5:19
  • @duskwuff It's run under CLI Commented Oct 20, 2017 at 6:03

2 Answers 2

3

It happens when you already create new shared memory segment and by some reason PHP did not close it. You need to access to already created segment by using "w" flag

$shared_memory = @shmop_open($key, "c", 0644, 255);
if (false === $shared_memory) {
    $shared_memory = shmop_open($key, "w", 0644, 255);
}
Sign up to request clarification or add additional context in comments.

Comments

0

Hey bro I ran into this issue myself and I figured out the fix, just run ftok in C/C++, the PHP ftok just doesn't work as it gives an unreliable key number, C's does however, print the key from a C program's ftok, copy and paste it in your PHP shmop_open(), it worked perfectly for me.

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.