Я только начал использовать общую память в PHP, чтобы что-то делать. Вот мой код
<?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);
Приведенный выше код порождает несколько дочерних процессов, которые содержат свои собственные сегменты разделяемой памяти. Сегменты общей памяти дочернего процесса используются для хранения данных после его обработки. И родительский процесс будет собирать данные из сегментов разделяемой памяти дочернего процесса после дочернего процесса Процесс завершен.
По моему скромному мнению, этот код должен работать без проблем.
Но некоторые неожиданные проблемы плюнули случайно.
Иногда все шло хорошо
/home/jhbian/pider/test/process/ReproduceProcessExample.php:60:
int(100)
Иногда это распалось
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
Кто-нибудь может указать, где шарнир?
Задача ещё не решена.
Других решений пока нет …