我刚开始在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);
上面的代码spaws了几个子进程,子进程各自持有自己的共享内存段,子进程的共享内存段用于存储处理后的数据,父进程会从子进程的共享内存中收集数据子进程完成后的片段。
In my humble opinion, this code should run without any problems. But some unexpected problems spat randomly.
有时进展顺利
/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
谁能指出铰链在哪里?
最佳答案
当您已经创建了新的共享内存段并且出于某种原因 PHP 没有关闭它时,就会发生这种情况。 您需要使用“w”标志访问已创建的段
$shared_memory = @shmop_open($key, "c", 0644, 255);
if (false === $shared_memory) {
$shared_memory = shmop_open($key, "w", 0644, 255);
}
关于php - 在 PHP 中使用共享内存时出现意外错误(PHP 警告 : shmop_open(): unable to attach or create shared memory segment 'Invalid argument' ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46842033/