V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
bearcat001
V2EX  ›  PHP

用PHP写daemon的问题

  •  
  •   bearcat001 · 2014-01-13 14:59:54 +08:00 · 4158 次点击
    这是一个创建于 3972 天前的主题,其中的信息可能已经有所发展或是发生改变。
    比如下面这样一个文件test.php
    <?php
    echo exec("nohup sleep 20 > /dev/null 2>&1 & echo $!");
    ?>

    在终端下执行php test.php可以将进程留在后台
    但是通过浏览器访问test.php的时候,不能在后台留下进程

    猜测可能是web进程中止同时把sleep也给中止了,要想一直留着,有什么好的解决方法吗?
    第 1 条附言  ·  2014-01-13 16:05:37 +08:00
    本来想图个省事直接在请求处理过程中就把这些事情做了,看来不太行
    还是得弄一个daemon来专门负责耗时任务的启动和中止
    第 2 条附言  ·  2014-01-13 16:09:32 +08:00
    感谢已送上,多谢各位
    15 条回复    2015-04-24 09:55:42 +08:00
    cdffh
        1
    cdffh  
       2014-01-13 15:06:25 +08:00   ❤️ 2
    用 setsid 试试?
    skydiver
        2
    skydiver  
       2014-01-13 15:08:50 +08:00 via Android   ❤️ 1
    楼主这种用法本来就是不对的,放弃吧。
    shiny
        3
    shiny  
       2014-01-13 15:09:30 +08:00   ❤️ 1
    1、用 ignore_user_abort 可以让用户中断连接的时候避免进程退出
    2、再需要设置 set_time_limit(0) 来避免超时的中断

    ucenter 的计划任务就是这么做的吧。
    breeswish
        4
    breeswish  
       2014-01-13 15:10:35 +08:00   ❤️ 1
    想要用作daemon,就用php-cli,并且关闭运行时间限制,不要用php-fpm或者mod-php
    h2ero
        5
    h2ero  
       2014-01-13 15:53:06 +08:00   ❤️ 1
    如果用的FastCGI可以用`fastcgi_finish_request();`
    bearcat001
        6
    bearcat001  
    OP
       2014-01-13 15:57:32 +08:00
    @cdffh 应该也是不行的
    bearcat001
        7
    bearcat001  
    OP
       2014-01-13 15:58:32 +08:00
    @skydiver 恩,还是在cli下写daemon吧
    bearcat001
        8
    bearcat001  
    OP
       2014-01-13 16:00:32 +08:00
    @shiny 如果是服务端启动一个耗时任务呢?这个任务写的时候就是CLI下运行,因为时长问题
    bearcat001
        9
    bearcat001  
    OP
       2014-01-13 16:00:51 +08:00
    @breeswish 恩,打算换了,多谢
    bearcat001
        10
    bearcat001  
    OP
       2014-01-13 16:03:31 +08:00
    @h2ero 多谢
    fastcgi_finish_request和ignore_user_abort类似都是继续执行当前脚本,没有办法让exec启动的cli命令驻留下来
    jasontse
        11
    jasontse  
       2014-01-13 16:04:35 +08:00 via iPad   ❤️ 1
    @bearcat001 如果是耗时任务就应该向daemon推送队列异步处理。
    bearcat001
        12
    bearcat001  
    OP
       2014-01-13 16:07:58 +08:00
    @jasontse 恩,打算这么做了,多谢~
    picasso250
        13
    picasso250  
       2014-01-14 16:21:20 +08:00
    php-resque
    judasnow
        14
    judasnow  
       2014-01-14 21:26:33 +08:00
    要是我 就定时执行一段 php 脚本(用crontab或者whatever)然后用redis模拟保存全局变量(每次脚本执行的时候 就从redis读取信息初始化 完成之后保存之)
    jevonszmx
        15
    jevonszmx  
       2015-04-24 09:55:42 +08:00
    如果你没服务器的权限,仅开发权限的话,就写php脚本,用crontab定时执行;

    如果你有服务器权限,可以给php编译一个PCNTL模块,官方文档在这里: http://php.net/manual/zh/book.pcntl.php,可以启动一个deamon在后台,比如有个大队列数据需要一直需要php同步入库,可以fork一个进程一直在后台跑,比crontab频率高,还可以多进程。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5419 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 08:27 · PVG 16:27 · LAX 00:27 · JFK 03:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.