Parallel tasks
Run several independent jobs across CPU cores at the same time, then wait for them all. Because processes don’t share memory, results come back through files or a database — not shared variables (see the mental model).
Start many, wait for all
Keep a handle to each Thread, start them, then join() every one:
<?php
require 'vendor/autoload.php';
use Flytachi\Winter\Thread\Thread;
$threads = [];
foreach (range(1, 8) as $reportId) {
$thread = new Thread(new ReportGenerator($reportId), 'Reports', 'ReportGenerator', "r-{$reportId}");
$thread->start();
$threads[] = $thread;
}
// Wait for everyone; count failures by exit code
$failed = 0;
foreach ($threads as $thread) {
if ($thread->join() !== 0) {
$failed++;
}
}
echo "Done. {$failed} failed.\n";Bound concurrency with a pool
Starting one process per item is fine for a handful of jobs. For hundreds, cap how many run at once so you don’t overwhelm the box:
<?php
require 'vendor/autoload.php';
use Flytachi\Winter\Thread\Thread;
$queue = range(1, 200);
$maxConcurrent = 4;
$running = [];
while ($queue || $running) {
// Top up to the concurrency limit
while (count($running) < $maxConcurrent && $queue) {
$id = array_shift($queue);
$thread = new Thread(new ReportGenerator($id), 'Reports', 'ReportGenerator', "r-{$id}");
$thread->start();
$running[] = $thread;
}
// Reap finished ones
foreach ($running as $i => $thread) {
if (!$thread->isAlive()) {
$thread->join(); // read exit code, free the process
unset($running[$i]);
}
}
$running = array_values($running);
usleep(50_000); // 50ms; avoid a busy loop
}Pick a sane limit
A good starting point is the number of CPU cores for compute-bound work, or higher for I/O-bound work (waiting on the network). Measure — don’t guess.
Collect results
Since children can’t hand objects back, have each task write its result somewhere the
parent can read after join():
// Inside run(): write a result the parent can pick up
file_put_contents("/tmp/report-{$this->reportId}.json", json_encode($rows));
// In the parent, after join():
$result = json_decode(file_get_contents("/tmp/report-{$reportId}.json"), true);The exit code from join() is the cheapest result channel of all — use it for plain
success/failure and reserve files or a database for real payloads.
Related
- Queue worker — dispatch jobs and pass arguments
- Graceful shutdown — timeouts and cancellation
- API reference —
isAlive(),join()