I have around 10 different requests for different servers and used to get the response sequentially in respective to the function call in my website.
Now, I want to call my function in parallel for different server request. Once I get the first response from any of the servers, then want to stop the the remaining processes.
Currently I am calling my function like so:
my_launch(1);
my_launch(2);
my_launch(3);
my_launch(4);
my_launch(5);
my_launch(6);
my_launch(7);
my_launch(8);
my_launch(9);
my_launch(10);
This executes sequentially; how can I run this code in parallel using PCNTL?
About PCNTL availibility
PHP has some PCNTL features built in but they are not enabled by default.
From php.net pcntl installation instructions:
You have to compile the CGI or CLI version of PHP with --enable-pcntl configuration option when compiling PHP to enable Process Control support.
Regarding parallelization
If you know the number of cores on your machine, then I would suggest dividing the work into that many divisions. Process control only works on *nix-like systems, so you probably have the nproc command available:
$numberOfProcessors = `nproc`;
You fork to get the proper number of processes running, divide the work between them and off you go. Dividing the work might be difficult, but I'm sure you'll figure it out.
Code dump
I was feeling generous so I went ahead and coded most of it for you. Be sure to understand it because it isn't quite finished.
Notes:
nproc, so if you don't have that utility you should replace it with the number of processes you want to make.Code:
$procs = `nproc`;
$iterations = 10;
$pids = array();
$iproc = -1;
if ($procs > $iterations) {
$procs = $iterations;
}
function my_launch($i, $proc) {
echo "Process $proc ran iteration $i.\n";
}
$pid = 0;
for ($i = 0; $i < $procs; $i++) {
$pid = pcntl_fork();
if ($pid > 0) {
// I am the parent process
$pids[$pid] = $pid;
} elseif ($pid == -1) {
//error occurred, use available processes only
$nproc = $i;
break;
} else {
//I am the child process.
$iproc = $i;
break;
}
}
$nproc = !empty($nproc) ? $nproc : $procs;
if ($nproc == 0) {
echo "NOTICE: Process could not be forked; proceeding in serial.\n";
for ($i = 0; $i < $iterations; $i++) {
my_launch($i, $iproc);
}
exit;
}
if ($nproc != $procs) {
echo "NOTICE: Only using $nproc processes out of the hoped $procs.\n";
}
$iterationsPerProcess = (int) ($iterations / $nproc);
// children do the main work.
if ($pid == 0) {
$stopAt = $iterationsPerProcess * ($iproc + 1);
for ($i = ($iproc * $iterationsPerProcess); $i < $stopAt; $i++) {
my_launch($i, $iproc);
}
}
if ($pid > 0) {
// parent process picks up the remainder of the work
$i = $nproc * $iterationsPerProcess;
for (; $i < $iterations; $i++) {
my_launch($i, "Main");
}
//wait for children to finish
$status = -1;
foreach ($pids as $createdIndex => $pid) {
pcntl_waitpid($pid, $status);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With