PHP-CLI模式守护进程

  1. 作者QQ:67065435 QQ群:669756510

  2. 本站内容全部为作者原创,转载请注明出处!

  3. 参考链接

  4. 安装PHP扩展:pcntl

  5. PHP源码

    <?php
    //ext:pcntl
    $pid = pcntl_fork();
    if ($pid === -1) {
        //Fork进程失败。
        echo "Fork进程失败。";
        exit;
    } elseif ($pid > 0) {
        //Fork进程成功。
        echo "Fork进程成功。";
        exit;
    }
    //现在pid一定为0了,走子进程
    $sid = posix_setsid();
    if ($sid == -1) {
        //使当前进程成为会话的领导者
        echo "守护进程创建失败";
        exit;
    } else {
        //守护进程创建成功
        while(true){
            sleep(100);
        }
    }
    # 执行php test.php
    # 执行ps aux|grep test.php
    # 会发现虽然有阻塞代码sleep(100),但是程序立即挂起了
    
  6. 简化代码

    <?php
    if (pcntl_fork() !== 0) {
        exit;
    } else{
        if (posix_setsid() == -1) {
            exit;
        } else {
            //Run some code...
        }
    }
    
  7. 配合systemd实现异常退出时自动启动

    1. 编写test.service

       vim /etc/systemd/system/test.service
      
       [Unit]
       Description=测试脚本
       After=default.target network.target
      
       [Service]
       User=www
       Group=www
       Type=forking
       ExecStart=/usr/bin/php /www/test.php
       PrivateTmp=true
       Restart=always
       RestartSec=5
       StartLimitInterval=0
      
       [Install]
       WantedBy=multi-user.target
      
       ESC
       :wq
      
    2. 重载systemd并启动test服务设置开机启动

       # 重载systemd
       systemctl daemon-reload
       # 启动test服务
       systemctl start test
       # 设置开机启动
       systemctl enable test
      
  8. 优点

    1. 能够以守护进程方式运行脚本

    2. 能够在进程异常退出时自动重启

    3. 能够在服务器开机时自动启动进程

    4. 不会产生僵尸进程,僵尸进程查看方式

       ps -A -o stat,ppid,pid,cmd | grep -e '^[Zz]'
      
    5. 父进程立即结束,子进程会成为init进程的子进程(孤儿进程),可以正常管理

       # 原理
       因为父进程立即执行结束,所以子进程会成为孤儿进程被init进程(所有进程的祖先)收
       养(即不会成为僵尸进程),当子进程执行结束或异常退出时,能够正常释放进程号供其它
       进程使用。
      
Copyright © 鲸小鱼 2012-∞ all right reserved,powered by Gitbook修订: 2000-10-10 00:00

results matching ""

    No results matching ""