1.什麼是守護進程?
守護進程,也就是通常說的daemon進程,是linux中的一種服務進程。它的特點是:
- 不佔用控制終端(後臺運行)
- 獨立於控制終端(tty是個?)
- 週期性運行
2.守護進程設計要素
後臺運行
守護進程需要獨立於任何一個控制終端。實現方法調用是通過創建子進程來充當守護進程,而父進程退出,這樣子進程就可以在後臺運行。
例如:
pid = fork();
if (pid>0)
exit(0);
else(pid == 0)
{
//守護進程
}
獨立於控制終端
守護進程不能佔用控制終端,因此需要在後臺運行。實現方法是調用setsid()函數。
pid = fork();
if(pid>0)
exit(0);
else(pid == 0)
{
setsid();
..........
}
擺脫父進程的影響
修改工作目錄
進程活動時,其工作目錄所在的文件系統不能卸載。例如:我們是從/mnt/usb目錄下啓動該守護進程的,那麼如果守護進程的工作目錄就是/mnt/usb,我們就無法在守護進程還在運行的情況下umount /mnt/usb。所以一般需要將守護進程的目錄切換到根目錄。
chdir(“/”);重設文件權限掩碼
文件權限掩碼是屏蔽掉文件權限中的對應位。比如掩碼是500,他就屏蔽了文件創建者的可讀與可執行權限。由於子進程要繼承父進程的文件權限掩碼,這勢必影響子進程中新創建的文件的訪問權限,爲避免該影響,就需要重新對子進程中的權限掩碼清零。通常的使用方法爲函數:
umask(0)
關閉文件描述符
同文件權限碼一樣,子進程還會從父進程那裏繼承一些已經打開了的文件。這些被打開的文件可能永遠不會被守護進程讀寫,但他們一樣消耗系統資源,而且會導致文件所在的文件系統無法卸載。因此在子進程中需要將這些文件關閉。
for(i=0;i<MAXFILE;i++)
close(i);
3.實例編寫
創建一個守護進程可以後運行向一個文件中寫入字符串;
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int main()
{
pid_t pid;
int i,fd;
int flag = 1;
char buffer[] = "I am daemon!";
//1.create a son process
pid = fork();
if (pid < 0)
{
printf("create son process fail!\n");
exit(1);
}
if (pid > 0)
exit(1);
//2.take away from terminal
setsid();
//3.1.change work diractory
chdir("/");
//3.2.clean mask
umask(0);
//3.3.close had open file
for(i = 0;i < 65535;i++)
close(i);
//4.guard process work content
while (1)
{
if((flag == 1) && (fd = open("/tmp/daemon.log",O_CREAT|O_WRONLY|O_APPEND,0600)))
{
printf("open file fail!/n");
flag = 0;
exit(1);
}
write(fd,buffer,strlen(buffer));
close(fd);
sleep(1);
}
return 0;
}