I understand how fork()
works at a high level and the pcntl_fork()
wrapper, but for some reason in my environment PHP only runs two child processes at a time. Take for example this simple code:
<?php
for ($i = 1; $i <= 5; ++$i) {
$pid = pcntl_fork();
if ($pid === -1) {
print "Could not fork!\n";
exit(1);
}
if (!$pid) {
print "-In child $i\n";
sleep(1);
print "In child $i\n";
exit($i);
} else {
print "Parent: forked $i\n";
}
}
while (pcntl_waitpid(0, $status) != -1) {
$status = pcntl_wexitstatus($status);
echo "Child $status completed\n";
}
The output I expect is something like this with total time around 1 second:
Parent: forked 1
-In child 1
Parent: forked 2
-In child 2
Parent: forked 3
-In child 3
Parent: forked 4
-In child 4
Parent: forked 5
-In child 5
In child 1
In child 2
In child 3
In child 4
In child 5
Child 1 completed
Child 2 completed
Child 3 completed
Child 4 completed
Child 5 completed
But what I actually get is this, with total execution time around 3.5 seconds:
Parent: forked 1
Parent: forked 2
Parent: forked 3
Parent: forked 4
Parent: forked 5
-In child 2
-In child 1
In child 2
Child 2 completed
-In child 3
In child 1
Child 1 completed
-In child 4
In child 3
Child 3 completed
-In child 5
In child 4
Child 4 completed
In child 5
Child 5 completed
So it appears that only two child processes are actually running at any given time. I can't find any explanation for this behavior...
When running the test on a production system which is Docker on a native Linux host I get the expected result, but why can't I reproduce it with the exact same container on my WSL2 host?
System Information
- I'm running this test in a very recent version of Docker Desktop via WSL2 on Windows 11.
- My system has 12 CPU cores (20 with hyperthreading -
nproc
prints "20" from both the WSL2 hostand from inside the docker container). - I have not changed the defaults in Docker Desktop or WSL config or used any resource control flags on the Docker container so CPU should not be restricted in any way.