因爲項目需要,需要寫一個守護進程,雖然用crontab也是可以實現的,但是crontab存在許多的不足(容易產生overlap,數據無法共享)
在別人的blog裏看到了守護進程的實現(unix),因此在linux環境中用php語言實現原理也是一樣的,因此可以借鑑。
先普及一下進程組,會話,控制終端:
a.一個會話可以對應多個進程組
b.一個會話只能對應一個控制終端
c.進程組組長無法創建一個新的會話,但是可以創建控制終端
b.進程組的組員可以創建一個新的會話,但無法創建控制終端
c.進程只能屬於一個進程組,也必定屬於一個進程組
創建守護進程:
1.使用pcntl_fork()創建一個子進程(同時退出父進程)
2.使用posix_setsid()新創建一個session
關於posix_setsid()的說明:
當它調用成功的時候,會創建一個新的session,並把當前的進程設置爲session leader。(從而脫離之前的session,之前的session是通過終端建立連接然後創建的。)同時也會脫離當前的進程組,創建一個新的進程組並且擔任進組組長。同時新創建的session沒有控制終端。
3.創建無法創建控制終端的進程(重新pcntl_fork一個子進程,退出父進程)
4.修改它的工作目錄(因爲工作目錄可能被umount)
5.修改工作目錄的權限(子進程繼承父進程的文件和文件權限)
6.處理SIGCHLD信號()
上代碼:
<?php
declare(ticks = 1);
$pid = pcntl_fork();
if($pid>0){
echo "parent pid".getmypid();
exit(0);
}
echo "child pid".getmypid();
chdir("/");
posix_setsid();
umask(0);
$pid_d = pcntl_fork();
if($pid_d > 0){
echo "Daemon PID $pid_d";
exit(0);
}
funzioneDemo();
function funzioneDemo(){
while(true){
$handle = fopen("/tmp/demon1e.log","w+");
fput($handle, time());
fclose($handle);
}
}
?>