Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly detach and remove shared memory between 2 processes in PHP?

I developed a way to make async tasks with PHP and it's working very well, until now.

The logic based in 3 extensions PCNTL, POSIX e Semaphore.

To have a full control of the master process and child process I must share the status of the task and the PID between them. These 2 variables are shared using shm_attach, the fork uses pcntl_fork.

The problem described in the title of this questions is related to the status of the task and the PID between them. These 2 variables are shared using shm_attach method because there is no more space available to share create a shared memory.

I use it for 2 moments: At constructor to create the shared memory

<?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;
}

And on the run method after forking the process

<?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

I think I'm doing something wrong because even though I'm using shm_detach and shm_remove the process sometimes returns the error PHP Warning: "shm_attach" failed for key No space left on the device in when I try to attach a new shared memory.

It is happening because some shared memory is detached and not removed from Shared memory segments, its the result of command ipcs -m :

ipcs -m result

The tasks are running for months before start doing this, so the one way to work around this problem I removed all shared memory identifiers with the command

ipcrm --all=shm

But I think it's silently growing and for sure it going to happen again.

How to prevent it?

like image 565
LeonanCarvalho Avatar asked Nov 07 '22 14:11

LeonanCarvalho


1 Answers

I think the process may be leaking memory due to objects being created and not destroyed inside the process' memory. one way you can analise this is by reviewing the process' memory usage and which queries are being sent, that may be causing this problem, if you can reproduce the creation and leakage of memory, then it should be possible to figure out a way to delete the created objects. this may be happening due to cursors left open among other factors. Have you considered using RabbitMQ for the async PHP tasks?

like image 169
Felipe Valdes Avatar answered Nov 15 '22 05:11

Felipe Valdes