我正在以这种方式使用shmop和pcntl exts: 1.分叉几个线程 2.在所有分叉线程和主线程中使用相同的键打开共享内存段。 3.写入/读取段。 4.删除并创建具有更大尺寸的原始名称的段。
有时我的代码工作正常,所有线程都会更改值,以便其他线程可以使用这些值。但在大多数情况下,线程的工作方式就像“没有提供id的段”。虽然上述投诉清楚地表明其中一个线程已经创建了具有相同ID的段。
要发现该段尚未创建,我尝试用'w'标志打开它,如果它抱怨不存在的段,我用'c'标志创建它。
执行此操作的方法:
protected function open() {
// probe
echo '=== KEY IS: '.$this->key.PHP_EOL;
$this->memory = shmop_open($this->key, 'w', 0, 0);
if ($this->memory === false) {
echo getmypid().'Create segment'.PHP_EOL;
$this->memory = shmop_open($this->key, 'c', 0666, strlen(serialize($this->initialValue)));
} else {
echo getmypid().'Open segment'.PHP_EOL;
}
}
我的输出在这里:
I am child: 6370
...
=== KEY IS: 1895898008
PHP Warning: shmop_open(): unable to attach or create shared memory segment in /home/debian/MiniThreader/src/CommonStorage.php on line 90
...
I am child: 6369
...
I am child: 6368
...
6370Create segment
Expanding size from 6 to 17
New size is 17
...
=== KEY IS: 1895898008
6369Open segment
...
Expanding size from 17 to 28
...
=== KEY IS: 1895898008
6368Open segment
...
Expanding size from 28 to 39
New size is 39
...
I am child: 6367
...
=== KEY IS: 1895898008
PHP Warning: shmop_open(): unable to attach or create shared memory segment in /home/debian/MiniThreader/src/CommonStorage.php on line 90
6367Create segment
...
Expanding size from 6 to 17
New size is 17
...
=== KEY IS: 1895898008
PHP Warning: shmop_open(): unable to attach or create shared memory segment in /home/debian/MiniThreader/src/CommonStorage.php on line 90
6366Create segment
string(6) ""
在此代码中,所有线程都尝试将其进程标识符添加到数组中,并在需要时增加它。
所以,我的问题是:为什么有时线程无法正常使用共享段,以及这种行为在较低级别的性质是什么?
是的,我正在使用信号量来防止同时扩展:
protected function expand($newsize) {
sem_acquire($this->sizeSemaphore);
shmop_delete($this->memory);
$this->memory = shmop_open($this->key, 'c', 0644, $newsize);
sem_release($this->sizeSemaphore);
}
答案 0 :(得分:0)
这个问题与记忆无关。析构函数(__destruct)就是答案。
对于那些面临共享内存或其他任何问题的人,请考虑重写可以删除数据的析构函数。
在我的案例中,使用内存段的类在析构函数中有删除内存段的代码。但是这个动作只是在主线程中。