fork-helper
fork-helper copied to clipboard
Warning: shmop_open(): unable to attach or create shared memory segment 'No space left on device'
This problem still exists in v2.3.0.
I was playing around with the sample code here and also had some errors and Exceptions, made by my own. When receiving those the script finishes without calling the cleanup()
method. I belive that this causes the problem.
So the problem only occurs when throwing exceptions? I think I can see how that would happen, I'll take a look at reproducing and resolving
Hmm I'm unable to reproduce the problem, please can you provide a script that demonstrates the issue?
So here is the code to reproduce:
<?php
require 'vendor/autoload.php';
use duncan3dc\Forker\Fork;
$fork = new Fork();
$fork->call(function () {
for ($i = 1; $i <= 3; $i++) {
echo "Process A - " . $i . "\n";
sleep(1);
}
});
$fork->call(function () {
for ($i = 1; $i < 3; $i++) {
echo "Process B - " . $i . "\n";
sleep(1);
}
});
throw new Exception();
sleep(1);
echo "Waiting for the threads to finish...\n";
$fork->wait();
echo "End\n";
Running this code for 10 to 20 times will end in a Exception Unable to open the shared memory block
thrown by the SharedMemory class. When calling $ ipcs -m
you will see that there are a lot of segments left. I believe this comes because the exception prevents the Adapter running the cleanup()
method which would delete the shared memory instances. So this problem could be solved by adding a shutdown function.
Hope it's clearer now :-)
Hi @Moskito89, you'll need a try/catch around your code to make sure you call $fork->wait()
.
Right now when a thread ends we don't know if others are still running, so we don't know when it's safe to clean up the shared memory, only the $fork->wait()
call tells us.
Another option would be to refactor so that everything is done in $fork->call()
calls and then the next thing called is $fork->wait()
, if you do anything between $fork->call()
and $fork->wait()
then you run the risk of leaving the shared memory (as you are seeing)
I understand this logic and the problem behind it. But if we'd use a shutdown function we could get sure, that the execution of this script always clears the shared memory, even when the execution fails/exits at some place. Wouldn't it be useful that way? If you don't think so feel free to close this topic :-)
I'd expect the shutdown function would be called within the threads too, thus deleting the shared memory early. You could perhaps register one after calling $fork->call()
in your code.
I'll leave the issue open for now, and try out a few things when I get some time :+1: