-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathphp_fork.txt
executable file
·52 lines (43 loc) · 2.46 KB
/
php_fork.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
Example script that uses pcntl_fork() to fork itself a few dozen times, and System V IPC functions to create a message queue,
let the child processes send data to it and the parent process read and display it.
#!/usr/bin/env php
<?php
// Create or attach to a message queue
$queue = msg_get_queue(ftok(__FILE__, 'a'), 0600); # set permissions so that only the owner can read/write to this queue
# ftok() creates a message queue key based on the file's inode and a single character project identifier. The latter lets
# one create several queues all based on/in the same file.
$child_count = 50;
// Fork child processes
for ($i = 0; $i < $child_count; $i++) {
\e[36m# pcntl_fork() splits the script \e[1mat the point where it is called\e[0;36m. The two copies of the script know what they are
\e[36m# based on the value of $pid: 0 for the child, positive int for the parent (it will be the child's PID) or -1 for failure.\e[0m
$pid = pcntl_fork();
if ($pid == -1) {
die('Could not fork');
} elseif ($pid) {
\e[36m# Parent process\e[0m
// Do nothing, will wait for child messages later
} else {
\e[36m# Child process: do all the Child things, send the results to the queue, then \e[1mexit\e[0m
$sleepTime = rand(1, 5);
sleep($sleepTime);
\e[36m# Send a message to the parent\e[0m
msg_send($queue, 1, "Child $i slept for $sleepTime seconds");
exit(0);
}
}
# Parent process waits to receive messages from all child processes
for ($i = 0; $i < $child_count; $i++) {
msg_receive($queue, 0, $msgType, 1024, $message, true);
echo "Received message: $message\\n";
}
# Destroy the message queue, otherwise it hangs around in memory. \e[38;5;208mipcs\e[0m will show you current message queues.
msg_remove_queue($queue);
# You might be tempted to use register_shutdown_function() for this (ChatGPT told me to!) but that will also fire as soon as
# the first child process exits, sooo.. don't.
# If all else fails, from the cli use \e[38;5;208mipcrm -q <msqid>\e[0m, where the msqid shows up under the output of \e[38;5;208mipcs\e[0m.
# Other considerations:
# - make sure the child process Always exits, and always sends something to the queue before doing so, wrapping it in a try/catch
# should work
# - counting $children++ inside the child process does not work, this variable will not be incremented in the parent process.
# you can increment it in the parent branch of the $pid fork.