畫江湖之 PHP 多程式開發 [實現守護程式化]

Krisji發表於2019-04-01

特點

  • 後臺執行
  • 不受任何終端控制
  • 可以由 系統啟動指令碼/etc/rc.local 、crontab任務、使用者shell 三種方式執行
如何守護程式化
1.建立子程式,終止父程式       
2.在子程式中建立新會話
3.改變工作目錄(預設繼承了父程式的當前工作目錄)
4.重設檔案建立掩碼(預設繼承了父程式的檔案建立掩碼)
5.關閉檔案描述符(預設繼承了父程式開啟了的檔案)
1.pcntl_fork, exit  建立子程式,退出程式
2.posix_setsid      讓當前程式變為主會話
3.chdir('/')        當前工作目錄改為 root 目錄
4.umask(0)      改變當前的 umask 為最寬鬆掩碼
5.fclose            關閉一個已開啟的檔案指標
<?php

function daemon() {
    // 1-1
    $pid = pcntl_fork();//fork一個子程式

    switch ($pid) {
    case -1:
        die('Create failed');
        break;
    case 0:
        // Child

        // 2.
        if ( ($sid = posix_setsid()) <= 0 ) {//讓當前的子程式變成住會話
            die("Set sid failed.\n");
        }

        // 3.
        if (chdir('/') === false) {//把當前目錄變成root目錄
            die("Change dir failed.\n");
        }

        // 4.
        umask(0);//重設定檔案的建立掩碼

        // 5.
        fclose(STDIN);//關閉一個開啟的檔案指標
        fclose(STDOUT);
        fclose(STDERR);

        break;
    default:
        // Parent

        // 1-2//退出主程式
        exit;
        break;
    }
}

function fork() {
    global $childs;

    $pid = pcntl_fork();

    switch ($pid) {
    case -1:
        die('Create failed');
        break;
    case 0:
        // Child
        while (true) {
            sleep(5);
        }

        break;
    default:
        // Parent

        $childs[$pid] = $pid;
        break;
    }
}

daemon();

$childs = [];

$count = 3;

for ($i = 0; $i < $count; $i++) {
    fork();
}

while ( count($childs) ) {
    if ( ($exit_id = pcntl_wait($status)) > 0 ) {
        unset($childs[$exit_id]);
    }

    if ( count($childs) < 3 ) {
        fork();
    }
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章