title: How to properly detach and remove shared memory between 2 processes in PHP?
body: <p>I developed a way to make async tasks with PHP and it's working very well, until now.</p>
  
  <p>The logic based in 3 extensions  <a href="http://php.net/manual/en/book.pcntl.php" rel="noreferrer">PCNTL</a>, <a href="http://php.net/manual/en/book.posix.php" rel="noreferrer">POSIX</a> e <a href="http://php.net/manual/en/book.sem.php" rel="noreferrer">Semaphore</a>.</p>
  
  <p>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  <a href="http://php.net/manual/en/function.shm-attach.php" rel="noreferrer">shm_attach</a>, the fork uses <a href="http://php.net/manual/en/function.pcntl-fork.php" rel="noreferrer">pcntl_fork</a>.</p>
  
  <p>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  <a href="http://php.net/manual/en/function.shm-attach.php" rel="noreferrer">shm_attach</a>  method because there is no more space available to share create a <a href="https://gerardnico.com/wiki/linux/shared_memory" rel="noreferrer">shared memory</a>.</p>
  
  <p>I use it for 2 moments:
  At constructor to create the shared memory</p>
  
  <pre><code>&lt;?php 
  //...
   final public function __construct() {
  self::$shmId = shm_attach((int) (ftok(self::$file, 'A') . self::$line), self::SHARED_MEMORY_SIZE);
  
              $this-&gt;var_key_pid = $this-&gt;alocatesharedMemory(getmypid(), 112112105100); //112112105100;
              $this-&gt;var_key_status = $this-&gt;alocatesharedMemory('PENDING', 11511697116117115);  //11511697116117115;
  }
  </code></pre>
  
  <p>And on the <code>run</code> method after forking the process</p>
  
  <pre><code>&lt;?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);
  </code></pre>
  
  <blockquote>
    <p>NOTE: The code is a little extensive and I put it into a gist
    <a href="https://gist.github.com/LeonanCarvalho/62c6fe0b62db8a478f502f84c5734c83" rel="noreferrer">https://gist.github.com/LeonanCarvalho/62c6fe0b62db8a478f502f84c5734c83</a></p>
  </blockquote>
  
  <p>I think I'm doing something wrong because even though I'm using <a href="http://php.net/manual/en/function.shm-detach.php" rel="noreferrer">shm_detach</a> and <a href="http://php.net/manual/en/function.shm-remove.php" rel="noreferrer">shm_remove</a> the process sometimes returns the error <strong>PHP Warning: "shm_attach" failed for key No space left on the device in</strong> when I try to attach a new shared memory.</p>
  
  <p>It is happening because some shared memory is detached and not removed from Shared memory segments, its the result of command <code>ipcs -m</code> :</p>
  
  <p><a href="https://i.stack.imgur.com/ldMAr.png" rel="noreferrer"><img src="https://i.stack.imgur.com/ldMAr.png" alt="ipcs -m result"></a></p>
  
  <p>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 </p>
  
  <pre><code>ipcrm --all=shm
  </code></pre>
  
  <p>But I think it's silently growing and for sure it going to happen again.</p>
  
  <p>How to prevent it?</p>