首页 > php框架 > Swoole > 正文

Swoole怎么异步执行一个耗时任务

尼克
发布: 2025-10-05 22:30:02
原创
689人浏览过
Swoole通过Task Worker、Process和协程实现异步任务处理。在Web服务中推荐使用Task Worker,将耗时任务如发邮件、数据导入等投递至task进程异步执行,避免阻塞主进程;可通过task()方法提交任务,在on('task')中处理,完成后触发on('finish')回调。对于非服务器场景,可使用Swoole\Process创建独立子进程执行任务,并通过Process::wait()回收防止僵尸进程。在协程环境下,可使用Co::exec执行外部命令,虽为同步执行但不阻塞其他协程,真正异步仍需结合task或进程。根据环境选择合适方式:Web用Task Worker,常驻脚本用Process,协程轻量操作用Co::exec。

swoole怎么异步执行一个耗时任务

Swoole 提供了多种方式来异步执行耗时任务,避免阻塞主进程或协程,提升服务响应性能。最常用的方式是使用 异步进程(Process)Task Worker 来处理耗时操作,比如发送邮件、写日志、数据导入导出等。

使用 Task Worker 异步处理任务

这是 Swoole 中推荐的做法,适用于 HTTP 服务器、WebSocket 服务器等场景。

在 Swoole 服务器中开启 task worker,将耗时任务投递到 task 进程中异步执行。

示例代码:

启动一个支持 task 的 Swoole 服务器:

$http = new Swoole\Http/Server("127.0.0.1", 9501);

// 设置 task 工作进程数量
$http->set([
    'task_worker_num' => 4,
]);

// 处理普通请求
$http->on('request', function ($request, $response) use ($http) {
    if (isset($request->post['action']) && $request->post['action'] == 'slow_task') {
        // 投递一个耗时任务
        $taskID = $http->task("模拟一个耗时任务,比如发送邮件");
        $response->end("任务已提交,ID: {$taskID}");
    } else {
        $response->end("Hello Swoole");
    }
});

// 处理任务(在 task 进程中执行)
$http->on('task', function ($server, $task) {
    // 模拟耗时操作
    sleep(5); // 实际中可能是调用 API、写文件、发短信等
    echo "任务完成:{$task->data}\n";

    // 可以返回结果给 finish 回调
    $server->finish("任务 {$task->id} 完成");
});

// 任务完成后的回调(可选)
$http->on('finish', function ($server, $taskID, $data) {
    echo "任务 {$taskID} 的结果:{$data}\n";
});

$http->start();
登录后复制

说明:

行者AI
行者AI

行者AI绘图创作,唤醒新的灵感,创造更多可能

行者AI100
查看详情 行者AI
  • task() 方法会把任务数据交给一个空闲的 task 进程异步执行。
  • on('task') 是任务实际执行的地方,不会影响主 Reactor 线程。
  • on('finish') 接收任务完成的通知,适合做后续处理。

使用 Swoole Process 创建独立异步进程

如果你不需要集成到服务器中,也可以手动创建子进程来异步执行任务。

$process = new Swoole\Process(function (Swoole\Process $worker) {
    // 子进程中执行耗时任务
    sleep(3);
    file_put_contents('/tmp/async.log', "任务完成时间:" . date('Y-m-d H:i:s') . "\n", FILE_APPEND);
    $worker->exit(0);
}, false, false);

$pid = $process->start();
echo "异步任务已启动,PID: {$pid}\n";

// 不等待,继续执行其他逻辑
登录后复制

你还可以通过 Process::wait() 在主进程回收子进程,防止僵尸进程。

协程环境下异步执行(Co::exec 或 go())

在 Swoole 协程环境中,如果只是“非阻塞”执行外部命令,可以使用 Co::exec

go(function () {
    $result = Co::exec("python /scripts/data_process.py"); // 执行脚本
    echo "脚本输出:{$result['output']}";
});
// 主协程继续执行,不阻塞
登录后复制

注意:这仍然是同步执行该命令,但放在协程里不会阻塞其他协程。若要真正异步,建议结合进程或 task 使用。

基本上就这些常用方式。根据你的运行环境选择:

  • Web 服务中用 Task Worker 最合适。
  • 常驻脚本可用 Swoole\Process
  • 协程内轻量操作可用 Co::exec 配合调度。

以上就是Swoole怎么异步执行一个耗时任务的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号