php進程daemon化的正確作法

[原文地址:https://blog.ti-node.com/blog...]php

daemon 音標 : ['di:mən] , 中文含義爲守護神或精靈的意思 . 其實它還有個意思 : 守護進程 .node

守護進程簡單地說就是能夠脫離終端而在後臺運行的進程 . 這在Linux中是很是常見的一種進程 , 好比apache或者mysql等服務啓動後 , 就會以守護進程的方式進駐在內存中 . mysql

以PHP爲例 , 假如我有個耗時間的任務須要跑在後臺 : 將全部mysql中user表中的2000萬用戶所有導入到redis中作預熱緩存 , 那麼這個任務估計一時半會是不會結束的 , 這個時候就須要編寫一個php腳本以daemon形式運行在系統中 , 結束後自動推出 .redis

在Linux中 , 大概有三種方式實現腳本後臺化 : sql

1 . 在命令後添加一個&符號 , 好比 php task.php & . 這個方法的缺點在於 若是terminal終端關閉 , 不管是正常關閉仍是非正常關閉 , 這個php進程都會隨着終端關閉而關閉 , 其次是代碼中若是有echo或者print_r之類的輸出文本 , 會被輸出到當前的終端窗口中 .apache

2 . 使用nohup命令 , 好比 nohup php task.php & . 默認狀況下 , 代碼中echo或者print_r之類輸出的文本會被輸出到php代碼同級目錄的nohup.out文件中 . 若是你用exit命令或者關閉按鈕等正常手段關閉終端 , 該進程不會被關閉 , 依然會在後臺持續運行 . 可是若是終端遇到異常退出或者終止 , 該php進程也會隨即退出 . 本質上 , 也並不是穩定可靠的daemon方案 .緩存

3 . 使用fork和setsid , 我暫且稱之爲 : *nix解決方案 . 具體看下代碼 :code

<?php
    // 一次fork  
    $pid = pcntl_fork();
    if ( $pid < 0 ) {
      exit( ' fork error. ' );
    } else if( $pid > 0 ) {
      exit( ' parent process. ' );
    }
    // 將當前子進程提高會會話組組長 這是相當重要的一步 
    if ( ! posix_setsid() ) {
      exit( ' setsid error. ' );
    }
    // 二次fork
    $pid = pcntl_fork();
    if( $pid < 0 ){
      exit( ' fork error. ' );
    } else if( $pid > 0 ) {
      exit( ' parent process. ' );
    }
    
    // 真正的邏輯代碼們 下面僅僅寫個循環以示例
    for( $i = 1 ; $i <= 100 ; $i++ ){
      sleep( 1 );
      file_put_contents( 'daemon.log', $i, FILE_APPEND );
    }
?>
相關文章
相關標籤/搜索