V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
MFWT
V2EX  ›  Linux

Linux 下, PHP 如何做同一程序的多任务队列?

  •  
  •   MFWT · 2023-03-20 19:50:27 +08:00 · 2025 次点击
    这是一个创建于 599 天前的主题,其中的信息可能已经有所发展或是发生改变。

    假设,我有一个程序叫做foo,我需要用 PHP 去调用这个程序做几个任务,任务之间毫不关联,不同任务传给这个程序的参数不同,任务执行完或者任务执行出错,程序都会退出(当然 exit_code 不同)

    我现在的想法是这样的,用 PHP 的 shell_exec 函数,后台方式运行程序:

    
    $bar = shell_exec('nohup /path/to/foo -d <一些参数> 2>&1 1>/path/to/log/<参数的 Hash>.log &');
    
    //下面有些别的程序来处理返回的$bar ,获取程序 PID ,并存进去数据库或者别的什么地方
    
    

    当前台提交任务(就是提交参数)的时候,就调用上面的脚本去运行 foo 这个程序,拿到 PID 之后再做处理

    我的问题是:

    1.这个方法有没有更优解?

    2.如何得知对应 PID 的程序已经正确执行完毕,或者说,这种情况下,如何检查 exit_code 是否为 0 (因为不确定错误报告会不会输出到 stderr )(附:不确定 jobs 命令能不能做到)?

    谢谢各位

    第 1 条附言  ·  2023-03-20 23:36:48 +08:00

    忘了一点重要的:这个运行的程序是耗时(比方说,下载东西)的,也就是说我需要某种异步执行的方式

    13 条回复    2023-03-26 19:37:58 +08:00
    howardlau
        1
    howardlau  
       2023-03-20 20:06:47 +08:00
    dobelee
        2
    dobelee  
       2023-03-20 23:29:04 +08:00
    很多年没写 php 了,之前是用 swoole 来做,起一个 tcp/http 服务接收参数,如果任务时间短可控,直接用 task 模型,否则开多进程。
    MFWT
        3
    MFWT  
    OP
       2023-03-20 23:37:13 +08:00
    @howardlau 我表达漏了一点:这个运行的程序是耗时(比方说,下载东西)的,也就是说我需要某种异步执行的方式
    panlatent
        4
    panlatent  
       2023-03-20 23:54:07 +08:00 via iPhone   ❤️ 1
    symfony/process
    sxbxjhwm
        5
    sxbxjhwm  
       2023-03-21 02:11:15 +08:00 via Android
    推荐 swoole
    maigebaoer
        6
    maigebaoer  
       2023-03-21 03:05:53 +08:00 via Android
    laravel 有任务队列,功能齐全,可以看官方文档去
    yekern
        7
    yekern  
       2023-03-21 09:08:33 +08:00
    Laravel Thinkphp 相关的框架都已经有完善的队列体系 随便找个文档看看就能用
    8355
        8
    8355  
       2023-03-21 09:10:30 +08:00
    workerman
    https://www.workerman.net/doc/workerman/worker/construct.html
    $task = new Worker();
    $task->onWorkerStart = function($task)
    {
    执行你的代码
    };

    可以封装成服务

    也可以用上面提到的 symfony/process 加到你的现有系统
    xiaoshouchen
        9
    xiaoshouchen  
       2023-03-21 09:25:44 +08:00
    pcntl ,PHP 的多进程库
    Seanfuck
        10
    Seanfuck  
       2023-03-21 10:24:49 +08:00
    多进程嘛,数据 /控制用参数+数据库或文件互通,简单点,开进程用 fsocketopen + ignore_user_abort 去请求 url
    xiaotianhu
        11
    xiaotianhu  
       2023-03-21 10:26:48 +08:00
    非 FPM ,cli 模式可以直接 fork 啊,或者用包装好的 symfony/process

    web 服务,简单的可以考虑,本地启个 Redis + 监听 cli 进程,用 Redis 通信,在 cli 里做。
    或者直接启动个 cli ,走 unix socket 通信,fpm 把任务发给 cli 去做。

    想折腾就 swoole ,异步更完善了。
    MFWT
        12
    MFWT  
    OP
       2023-03-21 10:42:40 +08:00
    @xiaotianhu 懂了,用 PHP 做个 CLI 的,再用 PHP 做和前端通信的 API ,前端访问-》 API 调用 CLI ,配合 PHP 原生的一些函数处理?
    julyclyde
        13
    julyclyde  
       2023-03-26 19:37:58 +08:00
    1 有
    2 无法。确定 jobs 不行

    你应该单独搞一个后台服务器,而不是直接由 php 来运行后台服务
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1317 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 17:51 · PVG 01:51 · LAX 09:51 · JFK 12:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.