php - 如何在 PHP 中正确分离和删除 2 个进程之间的共享内存?

标签 php multithreading asynchronous pthreads shared-memory

我开发了一种使用 PHP 执行异步任务的方法,到目前为止它运行良好。

基于 3 个扩展的逻辑 PCNTL , POSIX e Semaphore .

要完全控制主进程和子进程,我必须在它们之间共享任务状态和 PID。这 2 个变量使用 shm_attach 共享, fork 使用 pcntl_fork .

本题题目描述的问题与任务的状态以及它们之间的PID有关。这 2 个变量使用 shm_attach 共享方法,因为没有更多空间可用于共享创建 shared memory .

我使用了 2 次: 在构造函数中创建共享内存

<?php 
//...
 final public function __construct() {
self::$shmId = shm_attach((int) (ftok(self::$file, 'A') . self::$line), self::SHARED_MEMORY_SIZE);

            $this->var_key_pid = $this->alocatesharedMemory(getmypid(), 112112105100); //112112105100;
            $this->var_key_status = $this->alocatesharedMemory('PENDING', 11511697116117115);  //11511697116117115;
}

然后在 fork 进程后的run 方法上

<?php 
final public function run($parameters) {
//...
} else { //Frok process
                ignore_user_abort(); //I dont know why but must be set again.
                $sid = posix_setsid();
                self::$shmId = shm_attach((int) (ftok(self::$file, 'A') . self::$line), self::SHARED_MEMORY_SIZE);

NOTE: The code is a little extensive and I put it into a gist https://gist.github.com/LeonanCarvalho/62c6fe0b62db8a478f502f84c5734c83

我认为我做错了什么,因为即使我使用的是 shm_detachshm_remove该过程有时会返回错误 PHP Warning: "shm_attach"failed for key No space left on the device in 当我尝试附加新的共享内存时。

发生这种情况是因为一些共享内存已分离且未从共享内存段中删除,这是命令 ipcs -m 的结果:

ipcs -m result

任务在开始执行此操作之前运行了几个月,因此解决此问题的一种方法是我使用命令删除了所有共享内存标识符

ipcrm --all=shm

但我认为它正在悄然增长,并且肯定会再次发生。

如何预防?

最佳答案

我认为进程可能正在泄漏内存,因为对象在进程的内存中被创建但没有被销毁。您可以分析这一点的一种方法是查看进程的内存使用情况以及正在发送哪些查询,这可能会导致此问题,如果您可以重现内存的创建和泄漏,那么应该可以找到一种方法来删除创建的对象。这可能是由于游标保持打开状态以及其他因素造成的。 您是否考虑过将 RabbitMQ 用于异步 PHP 任务?

关于php - 如何在 PHP 中正确分离和删除 2 个进程之间的共享内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47287408/

相关文章:

python - 将来在不同的时间启动(非常短的) Action 时如何避免启动数百个线程

javascript - 尝试在循环中等待对象的元素

php - 如何通过下拉列表对数据进行排序

php - PHP 中的动态多态性

java - java中如何查找当前拥有锁的线程

c# - 我可以使用 async/await 来模拟后台 worker 吗?

javascript - 使用 axios 发布和获取请求的不同 header ,创建?

rest - 带有 Location header 的 JAX-RS AsyncResponse.resume()

php - 自动递增 UPDATE 查询 ID 或序列号

php - 如何在 MySQL 中设置年份数据类型