守护进程是什么?linux创建守护进程的步骤详解( 二 )


setsid();
说明:当进程是会话组长时setsid()调用失败 。但第一点已经保证进程不是会话组长 。setsid()调用成功后,进程成为新的会话组长和新的进程组长,并与原来的登录会话和进程组脱离 。由于会话过程对控制终端的独占性,进程同时与控制终端脱离 。
(3) 禁止进程重新打开控制终端
现在,进程已经成为无终端的会话组长 。但它可以重新申请打开一个控制终端 。可以通过使进程不再成为会话组长来禁止进程重新打开控制终端:
if(pid=fork())
exit(0);//结束第一子进程,第二子进程继续(第二子进程不再是会话组长)
(4)关闭打开的文件描述符
进程从创建它的父进程那里继承了打开的文件描述符 。如不关闭,将会浪费系统资源,造成进程所在的文件系统无法卸下以及引起无法预料的错误 。按如下方法关闭它们:
for(i=0;i 关闭打开的文件描述符close(i);>
(5) 改变当前工作目录
进程活动时,其工作目录所在的文件系统不能卸下 。一般需要将工作目录改变到根目录 。对于需要转储核心,写运行日志的进程将工作目录改变到特定目录如/tmpchdir("/")
(6)重设文件创建掩模
进程从创建它的父进程那里继承了文件创建掩模 。它可能修改守护进程所创建的文件的存取位 。为防止这一点,将文件创建掩模清除:umask(0);
(7)处理SIGCHLD信号
处理SIGCHLD信号并不是必须的 。但对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求 。如果父进程不等待子进程结束,子进程将成为僵尸进程(zombie)从而占用系统资源 。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能 。在Linux下可以简单地将SIGCHLD信号的操作设为SIG_IGN 。
signal(SIGCHLD,SIG_IGN);
【守护进程是什么?linux创建守护进程的步骤详解】这样,内核在子进程结束时不会产生僵尸进程 。这一点与BSD4不同,BSD4下必须显式等待子进程结束才能释放僵尸进程 。
三、创建守护进程
在创建之前我们先了解setsid()使用:
#include pid_t setsid(void);DESCRIPTIONsetsid()creates a new session if the calling process is not a processgroup leader.The calling process is the leader ofthenewsession,theprocess group leader of the new process group, and has no control-ling tty.The process group ID and session ID of thecallingprocessare set to the PID of the calling process.The calling process will bethe only process in this new process group and in this new session.//调用进程必须是非当前进程组组长,调用后,产生一个新的会话期,且该会话期中只有一个进程组,且该进程组组长为调用进程,没有控制终端,新产生的group ID 和 session ID 被设置成调用进程的PID
RETURN VALUEOn success, the (new) session ID of the callingprocessisreturned.Onerror,(pid_t) -1isreturned,and errno is set to indicate theerror.现在根据上述步骤创建一个守护进程:
以下程序是创建一个守护进程,然后利用这个守护进程每个一分钟向daemon.log文件中写入当前时间
01#include 02#include 03#include 04#include 05#include 06#include 07#include 08#define ERR_EXIT(m) 09do10{11perror(m);12exit(EXIT_FAILURE);13}14while (0);15void creat_daemon(void);16int main(void)17{18time_t t;19int fd;20creat_daemon();21while(1){22fd = open("daemon.log",O_WRONLY|O_CREAT|O_APPEND,0644);23if(fd == -1)24ERR_EXIT("open error");25t = time(0);26char *buf = asctime(localtime(&t));27write(fd,buf,strlen(buf));28close(fd);29sleep(60);30}31return 0;32}33void creat_daemon(void)34{35pid_t pid;36pid = fork();37if( pid == -1)38ERR_EXIT("fork error");39if(pid > 0 )40exit(EXIT_SUCCESS);41if(setsid() == -1)42ERR_EXIT("SETSID ERROR");43chdir("/");44int i;45for( i = 0; i

推荐阅读