PHP 异步IO扩展包 AsyncIO v2.0.0 发布

概述

AsyncIO 基于 PHP FiberWorkerman 实现的高性能异步 IO 扩展包,提供类似 Python asyncio 的 API 和功能。

特性

  • 🚀 基于 PHP Fiber - 原生协程支持,性能卓越

  • 完全事件驱动 - 零轮询,充分利用 Workerman 高性能

  • 🎯 并发控制 - gather, wait_for, 任务管理

  • 精确定时 - < 0.1ms 延迟,Timer 事件驱动

  • 🛡️ 异常处理 - 完整的错误传播和处理

  • 📦 简洁API - 类似 Python asyncio 的使用体验

安装

复制代码
composer require pfinalclub/asyncio

要求

  • PHP >= 8.1 (需要 Fiber 支持)

  • Workerman >= 4.1

快速开始

基础示例

复制代码
<?php
require_once__DIR__ . '/vendor/autoload.php';

usefunctionPfinalClub\Asyncio\{run, sleep};

// 定义一个异步函数
function hello_world(): mixed
{
    echo"Hello\n";
    sleep(1); // 异步睡眠 1 秒
    echo"World\n";
    return"Done!";
}

// 运行主函数
$result = run(hello_world(...));
echo"Result: {$result}\n";

并发任务

复制代码
<?php
usefunctionPfinalClub\Asyncio\{run, create_task, gather, sleep};

function task1(): string
{
    echo"Task 1 开始\n";
    sleep(2);
    echo"Task 1 完成\n";
    return"结果 1";
}

function task2(): string
{
    echo"Task 2 开始\n";
    sleep(1);
    echo"Task 2 完成\n";
    return"结果 2";
}

function main(): array
{
    // 创建任务
    $t1 = create_task(task1(...));
    $t2 = create_task(task2(...));
    
    // 并发等待所有任务完成
    $results = gather($t1, $t2);
    
    return $results; // ['结果 1', '结果 2']
}

run(main(...));

超时控制

复制代码
<?php
usefunctionPfinalClub\Asyncio\{run, wait_for, sleep};
usePfinalClub\Asyncio\TimeoutException;

function slow_task(): string
{
    sleep(5);
    return"完成";
}

function main(): void
{
    try {
        // 最多等待 2 秒
        $result = wait_for(slow_task(...), 2.0);
        echo"结果: {$result}\n";
    } catch (TimeoutException $e) {
        echo"任务超时: {$e->getMessage()}\n";
    }
}

run(main(...));

任务管理

复制代码
<?php
usefunctionPfinalClub\Asyncio\{run, create_task, await, sleep};

function background_task(string $name): string
{
    for ($i = 1; $i <= 5; $i++) {
        echo"{$name}: 步骤 {$i}\n";
        sleep(0.5);
    }
    return"{$name} 完成";
}

function main(): void
{
    // 创建多个后台任务
    $task1 = create_task(fn() => background_task("任务A"));
    $task2 = create_task(fn() => background_task("任务B"));
    
    // 等待一段时间
    sleep(2);
    
    // 检查任务状态
    echo"任务1 完成: " . ($task1->isDone() ? "是" : "否") . "\n";
    echo"任务2 完成: " . ($task2->isDone() ? "是" : "否") . "\n";
    
    // 等待任务完成
    $result1 = await($task1);
    $result2 = await($task2);
    
    echo"{$result1}, {$result2}\n";
}

run(main(...));

API 参考

核心函数

run(callable $main): mixed

运行主函数直到完成并返回结果。这是程序的主入口点。

复制代码
$result = run(my_function(...));
create_task(callable $callback, string $name = ''): Task

创建并调度一个任务,立即开始执行。

复制代码
$task = create_task(my_function(...), 'my-task');
async(callable $callback, string $name = ''): Task

create_task 的别名,更符合异步编程习惯。

复制代码
$task = async(my_function(...));
sleep(float $seconds): void

异步睡眠指定的秒数。必须在 Fiber 上下文中调用。

复制代码
sleep(1.5); // 睡眠 1.5 秒
await(Task $task): mixed

等待任务完成并返回结果。

复制代码
$result = await($task);
gather(Task ...$tasks): array

并发运行多个任务并等待它们全部完成。

复制代码
$results = gather($task1, $task2, $task3);
wait_for(callable|Task $awaitable, float $timeout): mixed

等待任务完成,如果超时则抛出 TimeoutException。

复制代码
try {
    $result = wait_for(my_task(...), 5.0);
} catch (TimeoutException $e) {
    echo "超时!\n";
}

事件循环

get_event_loop(): EventLoop

获取当前事件循环实例。

复制代码
$loop = get_event_loop();

Task 类

isDone(): bool

检查任务是否已完成。

getResult(): mixed

获取任务结果(如果任务未完成会抛出异常)。

cancel(): bool

取消任务。

addDoneCallback(callable $callback): void

添加任务完成时的回调。

Future 类

Future 表示一个未来的结果,可以手动设置。

复制代码
$future = create_future();

// 在某处设置结果
$future->setResult("结果");

// 等待结果
$result = await_future($future);

高级用法

HTTP 客户端

复制代码
use functionPfinalClub\Asyncio\{run, create_task, gather};
usePfinalClub\Asyncio\Http\AsyncHttpClient;

function main(): void
{
    $client = new AsyncHttpClient(['timeout' => 10]);
    
    // 单个请求
    $response = $client->get('https://api.example.com/users');
    echo"Status: {$response->getStatusCode()}\n";
    echo"Body: {$response->getBody()}\n";
    
    // 并发请求
    $task1 = create_task(fn() => $client->get('https://api.example.com/users/1'));
    $task2 = create_task(fn() => $client->get('https://api.example.com/users/2'));
    $task3 = create_task(fn() => $client->get('https://api.example.com/users/3'));
    
    $responses = gather($task1, $task2, $task3);
    
    foreach ($responses as $response) {
        echo"Status: {$response->getStatusCode()}\n";
    }
}

run(main(...));

监控工具

复制代码
use functionPfinalClub\Asyncio\{run, create_task, gather};
usePfinalClub\Asyncio\Monitor\AsyncioMonitor;

function main(): void
{
    $monitor = AsyncioMonitor::getInstance();
    
    // 创建任务
    $tasks = [
        create_task(fn() => my_task1()),
        create_task(fn() => my_task2()),
    ];
    
    gather(...$tasks);
    
    // 显示监控报告
    echo $monitor->report();
    
    // 导出 JSON
    echo $monitor->toJson();
}

run(main(...));

调试器

复制代码
use functionPfinalClub\Asyncio\run;
usePfinalClub\Asyncio\Debug\AsyncioDebugger;

function main(): void
{
    $debugger = AsyncioDebugger::getInstance();
    $debugger->enable();
    
    // 你的代码...
    
    // 显示调用链
    echo $debugger->visualizeCallChain();
    
    // 显示报告
    echo $debugger->report();
}

run(main(...));

与 v1.x 的区别

主要变更

v1.x (Generator) v2.0 (Fiber)
function f(): \Generator function f(): mixed
yield sleep(1) sleep(1)
yield $task await($task)
yield gather(...) gather(...)
run(generator()) run(callable)
相关推荐
wei_shuo5 小时前
平替 MongoDB 实践指南 | 金仓多模数据库助力电子证照系统国产化改造
数据库·1024程序员节·king base·金仓多模数据
草莓熊Lotso5 小时前
《算法闯关指南:优选算法--二分查找》--23.寻找旋转排序数组中的最小值,24.点名
开发语言·c++·算法·1024程序员节
Sylvia@8885 小时前
19.管理基本存储
linux·运维·1024程序员节
njsgcs5 小时前
动态识别文件夹下flask接口
1024程序员节
安当加密5 小时前
CAS汽车固件签名:从“完成签名”到“安全治理”的演进之路
1024程序员节
傻童:CPU5 小时前
C语言需要掌握的基础知识点之矩阵
c语言·1024程序员节
摘星编程5 小时前
技术引领场景革新|合合信息PRCV论坛聚焦多模态文本智能前沿实践
合合信息·1024程序员节·textin·多模态文本·fidok
ink@re5 小时前
消息队列集群——RabbitMQ
分布式·rabbitmq·1024程序员节
cs阿坤dn5 小时前
SQL-Server2019离线部署安装【CentOS7.4】
1024程序员节