PHP 如何實(shí)現(xiàn)守護(hù)進(jìn)程?針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。
10余年的湘東網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開(kāi)發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。網(wǎng)絡(luò)營(yíng)銷推廣的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整湘東建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。成都創(chuàng)新互聯(lián)從事“湘東網(wǎng)站設(shè)計(jì)”,“湘東網(wǎng)站推廣”以來(lái),每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
守護(hù)進(jìn)程
守護(hù)進(jìn)程作為一種常駐進(jìn)程服務(wù),很常見(jiàn),例如 PHP-FPM, NGINX,redis,都需要一個(gè)父進(jìn)程來(lái)支持整個(gè)服務(wù)。但是用 PHP 編寫(xiě)守護(hù)進(jìn)程不多見(jiàn),今天就來(lái)用 PHP 來(lái)實(shí)現(xiàn)一下。
步驟
● fork 子進(jìn)程
● 父進(jìn)程退出
● 設(shè)置新的會(huì)話
● 重置文件掩碼
● 關(guān)閉標(biāo)準(zhǔn)輸入輸出
實(shí)現(xiàn)
我們對(duì)著以上的步驟來(lái)實(shí)現(xiàn),在這之前需要 pcntl 和 posix 擴(kuò)展,請(qǐng)確保安裝了。
function daemon() { $pid = pcntl_fork(); // fork 失敗 if ($pid < 0) { exit('fork failed'); } else if ($pid > 0) { // 退出父進(jìn)程 exit(0); } // 設(shè)置新的會(huì)員 // setsid 有幾個(gè)注意點(diǎn) // 不能是進(jìn)程組的組長(zhǎng)調(diào)用 // 對(duì)于進(jìn)程組組員調(diào)用會(huì)產(chǎn)生新的會(huì)話和進(jìn)程組,并成為該進(jìn)程組的唯一成員,調(diào)用的進(jìn)程將脫離終端 if (posix_setsid() < 0) { exit('set sid failed'); } // 重置文件掩碼 umask(0); // 切換工作目錄 chdir('/'); // 關(guān)閉標(biāo)準(zhǔn)輸入輸出 fclose(STDIN); fclose(STDOUT); fclose(STDERR); }
細(xì)節(jié)
// 獲取進(jìn)程ID var_dump(posix_getpid()); // 獲取進(jìn)程組ID var_dump(posix_getpgid(posix_getpid())); // 獲取進(jìn)程會(huì)話ID var_dump(posix_getsid(posix_getpid()));
三者結(jié)果相同,說(shuō)明了該進(jìn)程即使進(jìn)程組的組長(zhǎng),也是會(huì)話首領(lǐng)。
為什么需要 umask (0)
當(dāng)你在 linux 調(diào)用 umask 的時(shí)候你會(huì)看到一個(gè)掩碼值,這個(gè)掩碼決定了你創(chuàng)建文件權(quán)限范圍,例如本人當(dāng)前機(jī)器的 umask 為
0022
文件的最大權(quán)限是 0666,而目錄的最大權(quán)限是 0777, 那么當(dāng)前用戶的創(chuàng)建的目錄權(quán)限就是 0755,對(duì)于當(dāng)前用戶而言就是 rwx-rx-rx 權(quán)限。而文件則是 0644,對(duì)于當(dāng)前用戶而言 rw-r-r 權(quán)限。所以如果沒(méi)有重置掩碼的話,那么對(duì)于目錄而言就是 0755,而文件則是 0644 了。
注意
如果你在進(jìn)程使用了 echo var_dump 等函數(shù),一定要把標(biāo)準(zhǔn)輸出等重定向到其他文件流中。新增加下面代碼就可以了。
global $stdin, $stdout, $stderr; $stdin = fopen('/dev/null', 'r'); $stdout = fopen('/www/php/txt.txt','wb'); $stderr = fopen('/dev/null', 'wb');
因?yàn)樵谏厦嬉呀?jīng)關(guān)閉了標(biāo)準(zhǔn)輸入輸出,此時(shí)文件描述符 fd 已經(jīng)沒(méi)有,所有重新打開(kāi)之后 fd 從非負(fù)開(kāi)始依次是 0,1,2。正好作為標(biāo)準(zhǔn)輸入輸出的文件。當(dāng)然重定向到那里需要你自己設(shè)置。
最后的二次 fork
這個(gè)問(wèn)題需要好好斟酌,因?yàn)槭欠潜仨毜?。目前想不到有什么?chǎng)景下必須兩次 Fork。
關(guān)于PHP 如何實(shí)現(xiàn)守護(hù)進(jìn)程問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識(shí)。