PHP code example of kode / parallel
1. Go to this page and download the library: Download kode/parallel library . Choose the download type require .
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
kode / parallel example snippets
function Kode\Parallel\map;
use function Kode\Parallel\engine;
// 自动按 CPU 核心数并行处理,结果保持输入键序
$sizes = map(['a.jpg', 'b.jpg', 'c.jpg'], static fn(string $file): int => strlen($file));
echo '当前引擎: ' . engine() . PHP_EOL; // parallel / process / sync
print_r($sizes);
Kode\Parallel\Runtime\Runtime;
$runtime = new Runtime();
// 并行执行 5 个任务
$futures = [];
for ($i = 0; $i < 5; $i++) {
$futures[] = $runtime->run(
fn($args) => $args['n'] * $args['n'],
['n' => $i + 1]
);
}
foreach ($futures as $f) {
echo "结果: " . $f->get() . "\n";
}
$runtime->close();
use Kode\Parallel\Runtime\Runtime;
use Kode\Parallel\Concurrency\Channel;
$runtime = new Runtime();
$ch = Channel::make();
$runtime->run(fn() => $ch->send(range(1, 100)));
$runtime->run(fn() => $ch->send(range(101, 200)));
$sum = fn() => array_sum($ch->recv()) + array_sum($ch->recv());
echo "总和: " . $runtime->run($sum)->get() . "\n";
$runtime->close();
use Kode\Parallel\Fiber\Fiber;
$fiber = new Fiber(function() {
$value = Fiber::suspend('暂停');
return "收到: $value";
});
echo $fiber->start() . "\n"; // 暂停
echo $fiber->resume('恢复数据') . "\n"; // 收到: 恢复数据
use Kode\Parallel\Engine\EngineFactory;
use Kode\Parallel\Runtime\Runtime;
EngineFactory::available(); // ['parallel' => true, 'sync' => true] (ZTS + ext-parallel)
EngineFactory::detect(); // 'parallel'
$runtime = new Runtime(); // 自动选择(真线程)
$runtime = new Runtime(null, 'sync'); // 显式指定同步回退
// 需要多进程时,把 kode/process 接入统一调度(详见 docs/ENGINE.md)
EngineFactory::register(
name: 'process',
factory: static fn(?string $bootstrap, int $workers) => new MyProcessEngine($bootstrap, $workers),
supported: static fn(): bool => extension_loaded('pcntl'),
);
use Kode\Parallel\Future\Futures;
$futures = $runtime->runAll([
fn(array $a) => file_get_contents('https://example.com/a'),
fn(array $a) => file_get_contents('https://example.com/b'),
]);
$results = Futures::all($futures, timeoutMs: 5000); // 任一失败即抛出
$settled = Futures::settle($futures); // 全部结束,返回状态数组
$fastest = Futures::any($futures, 3000); // 第一个成功的结果
use Kode\Parallel\Pool\WorkerPool;
$pool = new WorkerPool(concurrency: 8);
$results = $pool->map(range(1, 100), static fn(int $n): int => $n * $n);
$report = $pool->mapSettled($urls, $fetch); // 不因单个失败中断
$stream = $pool->map($rowGenerator, $render); // 输入可为数组或任意可迭代(生成器只遍历一次,先归整再派发)
$stats = $pool->stats(); // engine / submitted / completed / failed / pending
$pool->close();
use Kode\Parallel\Pool\ThreadPool;
$pool = new ThreadPool(8);
// submit 立即返回,不等待线程空闲;可一口气预排海量任务
$f = $pool->submit(static fn(array $a): int => heavy($a['x']), ['x' => $i]);
// 队列积压由工作线程异步消费;需要时再阻塞取结果
$value = $f->get();
// 也可等全部完成
$pool->wait();
$pool->close();
use Kode\Parallel\Concurrency\Lock;
use Kode\Parallel\Concurrency\Atomic;
use Kode\Parallel\Concurrency\Barrier;
use Kode\Parallel\Concurrency\Channel;
// 互斥锁(可命名,跨进程共享)
$lock = Lock::named('order');
$lock->withLock(function () {
// 临界区
});
// 原子计数器(跨进程安全的自增,CAS 支持)
$counter = new Atomic(0);
$counter->inc();
$counter->compareAndSwap(1, 10);
// 屏障:N 个参与者到齐后整体放行,并自动进入下一代
$barrier = Barrier::named(4, 'phase-1');
$barrier->wait();
// 单运行时消息通道(有界/无界)
$ch = Channel::bounded(8);
$ch->send($item);
$item = $ch->recv();
use Kode\Parallel\Future\Futures;
$future = runtime()->run(fn($a) => $a['x'] + 1, ['x' => 41]);
$chained = $future
->then(fn($v) => $v * 2) // 成功时变换
->map(fn($v) => "result:$v") // 同 then,仅做映射
->catch(fn($e) => "fallback"); // 失败时兜底
echo $chained->get(); // "result:84"
// 非阻塞选择:返回第一个已就绪的 Future(对标 parallel\Events::poll / Swoole Channel::select)
$ready = Futures::select([$f1, $f2, $f3], timeoutMs: 1000);
$runtime = new Runtime();
$runtime = new Runtime('/path/to/bootstrap.php');
$future = $runtime->run($task, $args);
$future = $runtime->run(fn($a) => $a['x'] + $a['y'], ['x' => 1, 'y' => 2]);
$runtime->isRunning();
$runtime->pendingCount(); // 尚未回收的任务数(run/isRunning 会自动回收已完成的 Future)
$runtime->getBootstrap();
$runtime->close();
use Kode\Parallel\Concurrency\Channel;
// 无界限通道
$ch = Channel::make();
// 有界限通道(容量为10)
$ch = Channel::bounded(10);
// 发送/接收
$ch->send($data);
$data = $ch->recv();
$ch->close();
$ch->isEmpty();
$future->get(); // 阻塞获取
$future->getOrNull(); // 非阻塞获取
$future->wait(1000); // 等待1秒
$future->cancel(); // 取消任务
use function Kode\Parallel\Util\pipe;
// 类似 Unix 的管道操作
$result = pipe(
' Hello World ',
'trim',
'strtoupper',
fn($s) => str_replace('WORLD', 'PHP', $s)
);
echo $result; // 输出: HELLO PHP
use function Kode\Parallel\Util\clone_with;
class Color {
public function __construct(
public int $red,
public int $green,
public int $blue,
public int $alpha = 255
) {}
}
$blue = new Color(79, 91, 147);
$transparent = clone_with($blue, ['alpha' => 128]);
// CurlMulti 自动支持连接复用
$curl = new CurlMulti();
$curl->get('https://api.example.com/1');
$curl->get('https://api.example.com/2');
$curl->get('https://api.example.com/3');
$results = $curl->execute(); // 自动复用连接
use Kode\Parallel\Fiber\Fiber;
use Kode\Parallel\Fiber\FiberManager;
// 单个 Fiber
$fiber = new Fiber(function($input) {
$step1 = Fiber::suspend('第一步完成');
return "最终结果: {$step1}";
});
$fiber->start();
$result = $fiber->resume('恢复数据');
// Fiber 管理器
$manager = new FiberManager();
$manager->spawn('task1', fn() => compute1());
$manager->spawn('task2', fn() => compute2());
$manager->startAll();
$results = $manager->collect();
use Kode\Parallel\Concurrency\Lock;
use Kode\Parallel\Concurrency\Semaphore;
use Kode\Parallel\Concurrency\Atomic;
// Lock - 互斥锁(可命名,跨进程共享)
$lock = Lock::named('order');
$lock->withLock(function() {
// 临界区代码
});
// Semaphore - 信号量(限流,最多3个并发)
$sem = new Semaphore(3);
$sem->withPermits(1, function() {
// 限流执行
});
// Atomic - 原子计数器(跨进程安全自增 + CAS)
$counter = new Atomic(0);
$counter->inc();
$counter->compareAndSwap(1, 10);
use Kode\Parallel\Pipe\Pipe;
$pipe = Pipe::make('my_pipe');
$pipe->write('Hello');
$data = $pipe->read();
use Kode\Parallel\Curl\CurlMulti;
$curl = new CurlMulti();
$curl->get('https://api.example.com/users');
$curl->post('https://api.example.com/posts', ['title' => 'Hello']);
$results = $curl->execute();
use Kode\Parallel\Runtime\Runtime;
use Kode\Parallel\Concurrency\Channel;
$runtime = new Runtime();
$channel = Channel::bounded(10);
$producer = fn() => produce($channel);
$consumer = fn() => consume($channel);
$runtime->run($producer);
$runtime->run($consumer);
use Kode\Parallel\Pool\WorkerPool;
$pool = new WorkerPool(11); // 线程数 ≈ CPU 核数
// 直接 map() 即可,元素较多时内部自动批量合并;批大小 auto(元素数 / 线程数 / 4,封顶 1024)
$results = $pool->map($messages, static fn (mixed $m): string => render($m));
// 群发场景用容错版:单条失败不连累同批其他元素
$settled = $pool->mapBatchSettled($recipients, static fn (array $u): string => send($u));
foreach ($settled as $key => $r) {
if ($r['status'] === 'rejected') {
// reason 恒为 ParallelException;原始异常类名见 getContext()['class']
$retry[$key] = $r['reason']->getMessage();
}
}
$pool->close();
use Kode\Parallel\Curl\CurlMulti;
$urls = [];
foreach ($users as $u) {
$urls['u' . $u['id']] = "https://api.example.com/notify?uid={$u['id']}";
}
// 滑动窗口:始终保持 16 个在途连接,完成一个补一个
$results = CurlMulti::fetch($urls, concurrency: 16, timeout: 30);
// ✅ 推荐:简单、单一职责
$task = new Task(fn($args) => processData($args['data']));
// ❌ 避免:复杂业务逻辑
$task = new Task(function($args) {
// 大量代码...
});
try {
$runtime = new Runtime('/invalid/path.php');
} catch (ParallelException $e) {
echo "错误: " . $e->getMessage() . "\n";
}
$runtime = new Runtime();
try {
$result = $runtime->run($task)->get();
} finally {
$runtime->close();
}
// ❌ 不行
$task = new Task(function() { yield 1; });
// ✅ 改用返回数组
$task = new Task(function() { return [1, 2, 3]; });
// ✅ 使用 Channel
$channel = Channel::make();
$runtime->run(fn($args) => $args['ch']->send($data), ['ch' => $channel]);