守護行程
守護行程作為一種常駐進程服務,很常見,例如 PHP-FPM, NGINX,REDIS,都需要一個父進程來支援整個服務。但是用 PHP 編寫守護行程不多見,今天就來用 PHP 來實現一下。
步驟
● fork 子進程
● 父進程退出
● 設定新的對談
● 重置檔案掩碼
● 關閉標準輸入輸出
實現
我們對著以上的步驟來實現,在這之前需要 pcntl 和 posix 擴充套件,請確保安裝了。
function daemon() { $pid = pcntl_fork(); // fork 失敗 if ($pid < 0) { exit('fork failed'); } else if ($pid > 0) { // 退出父進程 exit(0); } // 設定新的會員 // setsid 有幾個注意點 // 不能是行程群組的組長呼叫 // 對於行程群組組員呼叫會產生新的對談和行程群組,並成為該行程群組的唯一成員,呼叫的進程將脫離終端 if (posix_setsid() < 0) { exit('set sid failed'); } // 重置檔案掩碼 umask(0); // 切換工作目錄 chdir('/'); // 關閉標準輸入輸出 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('/dev/null', 'r'); $stdout = fopen('/www/php/txt.txt','wb'); $stderr = fopen('/dev/null', 'wb');
因為在上面已經關閉了標準輸入輸出,此時檔案描述符 fd 已經沒有,所有重新開啟之後 fd 從非負開始依次是 0,1,2。正好作為標准輸入輸出的檔案。當然重定向到那裡需要你自己設定。
最後的二次 fork
這個問題需要好好斟酌,因為是非必須的。目前想不到有什麼場景下必須兩次 Fork。
以上就是PHP 實現守護行程的詳細內容,更多請關注TW511.COM其它相關文章!