首頁  >  文章  >  後端開發  >  PHP 實作守護程式

PHP 實作守護程式

藏色散人
藏色散人轉載
2019-08-09 14:13:285430瀏覽

PHP 實作守護程式

守護程式

#守護程式作為一種常駐程式服務,很常見,例如PHP-FPM, NGINX,REDIS,都需要一個父進程來支援整個服務。但用 PHP 寫守護程式不多見,今天就來用 PHP 來實作一下。

步驟

● fork 子程序

● 父程序退出

● 設定新的會話

#● 父程序退出

● 設定新的會話

# ● 重置檔案遮罩● 關閉標準輸入輸出

實作

我們對著以上的步驟來實現,在這之前需要pcntl和posix 擴展,請確保安裝了。

function daemon() {
    $pid = pcntl_fork();
    // fork 失败
    if ($pid < 0) {
        exit(&#39;fork failed&#39;);
    } else if ($pid > 0) {
       // 退出父进程
        exit(0);
    }
    // 设置新的会员
    // setsid 有几个注意点
    // 不能是进程组的组长调用
    // 对于进程组组员调用会产生新的会话和进程组,并成为该进程组的唯一成员,调用的进程将脱离终端
    if (posix_setsid() < 0) {
        exit(&#39;set sid failed&#39;);
    }
    // 重置文件掩码
    umask(0);
    // 切换工作目录
    chdir(&#39;/&#39;);
    // 关闭标准输入输出
    fclose(STDIN);
    fclose(STDOUT);
    fclose(STDERR);
}

細節

// 获取进程ID
var_dump(posix_getpid());
// 获取进程组ID
var_dump(posix_getpgid(posix_getpid()));
// 获取进程会话ID    
var_dump(posix_getsid(posix_getpid()));
三者結果相同,說明了該進程即使進程組的組長,也是會話首領。

為什麼需要umask (0)

當你在linux 呼叫umask 的時候你會看到一個掩碼值,這個掩碼決定了你建立檔案權限範圍,例如本人目前機器的umask 為

0022

檔案的最大權限是0666,而目錄的最大權限是0777, 那麼目前使用者的建立的目錄權限就是0755,對於目前使用者而言就是rwx-rx-rx 權限。而檔案則是 0644,對於目前使用者而言 rw-r-r 權限。所以如果沒有重置遮罩的話,那麼對於目錄而言就是 0755,而檔案則是 0644 了。

注意

如果你在進程使用了 echo var_dump 等函數,一定要把標準輸出等重定向到其他檔案流。新增加下面程式碼就可以了。

global $stdin, $stdout, $stderr;
$stdin = fopen(&#39;/dev/null&#39;, &#39;r&#39;);
$stdout = fopen(&#39;/www/php/txt.txt&#39;,&#39;wb&#39;);
$stderr = fopen(&#39;/dev/null&#39;, &#39;wb&#39;);
因為在上面已經關閉了標準輸入輸出,此時檔案描述子 fd 已經沒有,所有重新開啟之後 fd 從非負開始依序是 0,1,2。正好作為標準輸入輸出的檔案。當然重定向到那裡需要你自己設定。

最後的二次 fork#########這個問題需要好好斟酌,因為是非必須的。目前想不到有什麼場景下必須兩次 Fork。 ###

以上是PHP 實作守護程式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:learnku.com。如有侵權,請聯絡admin@php.cn刪除