многопроцессорная обработка — непредвиденная ошибка при использовании разделяемой памяти в PHP (предупреждение PHP: shmop_open (): невозможно присоединить или создать сегмент разделяемой памяти «Неверный аргумент»)

Я только начал использовать общую память в 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

Кто-нибудь может указать, где шарнир?

3

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]