parallelxはPocketMine-MP用の マルチプロセス並列実行拡張
AsyncTaskのように、単一プロセス内でタスクを処理するのではなく、
外部プロセスプールでPHPクロージャを安全に並列実行 し、
結果をメインスレッド(PMMPのプロセス)へ返すことが可能
flowchart LR
subgraph PM[🏗 PocketMine-MP Main Process]
A1["parallelx_submit()"]
A2["C Extension Layer"]
A3["Dispatcher / Callback"]
A1 --> A2 --> A3
end
subgraph Pool[⚙️ Worker Process Pool]
direction TB
W1["Worker #1<br>executes closure"]
W2["Worker #2<br>executes closure"]
W3["Worker #3<br>executes closure"]
end
A2 -->|enqueue task| Pool
Pool -->|send result via pipe| A3
public function onEnable(): void {
// optional: PHPのパス、workerscriptのパス、オートローダのパス
$phpCli = '/home/pmmp/pmmp/bin/php7/php';
$workerScript = $this->getDataFolder() . 'parallelx_worker.php';
$autoload = '/path/to/server/vendor/autoload.php';
parallelx_init(4, $phpCli, $workerScript, $autoload);
// 1tick周期でpoll
$this->getScheduler()->scheduleRepeatingTask(new \pocketmine\scheduler\CallbackTask(function(): void {
parallelx_poll();
}), 1);
}
use ParallelX\Helper;
$closure = function($n) {
$s = 0;
for ($i = 0; $i < $n; ++$i) $s += ($i % 2 ? -1 : 1);
return $s;
};
$desc = Helper\extract_closure_descriptor($closure);
$token = parallelx_register($desc['source'], $desc['bound_b64']);
parallelx_submit_token($token, [2000000], function($res) {
if ($res['success']) {
$payload = unserialize(base64_decode($res['data']));
$this->getLogger()->info("Result: " . var_export($payload['return'], true));
} else {
$this->getLogger()->warning("failed: " . $res['data']);
}
});ビルド
phpize
./configure --with-php-config=php-config CC=gcc
make clean
make CC=gcc -j$(nproc)
make installphp.iniに追記
extension=parallelx