守护进程的一些说明

1、实现一个守护进程的实例如下:

#include "unp.h"
#include <syslog.h>
#define MAXFD 64
extern int daemon_proc;
void daemon_init(const char * pname,int facility){
    int i;
    pid_t pid;
 
    if((pid = Fork())!=0) //调用fork,终止父进程,留下子进程继续运行。
        exit(0);
 
    setid(); //创建一个新的登陆会话session
    Signal(SIGHUP,SIG_IGN); //忽略SGIHUP信号并在此调用fork
 
    if((pid=Fork())!=0) //确保将来即使打开一个终端设备,也不会自动获得控制终端。
        exit(0);
 
    daemon_proc = 1; //非零时,出错处理函数将调用syslog函数取代fprintf输出到标准错误输出
 
    chdir("/");
    umask(0);//将工作目录改到根目录
 
    for(i=0;i<MAXFD;i++) //关闭守护进程从运行开始打开的所有文件描述字
        close(i);
 
    openlog(pname,LOG_PID,facility);
}

2、实现一个守护进程最重要的两步就是:fork子进程,退出父进程;调用setsid()函数创建会话。我在一个练习中就只使用了这两步,没有像1中的示例一样再做其他的操作如更改掩码、关闭描述符操作等。代码如下:

if(fork() > 0) //第1步
    exit(0);
 
setsid(); //第2步
	
if(fork() > 0)//第3步:确保将来即使打开一个终端设备,也不会自动获得控制终端。
    exit(0); 

        之所以需要第3步是因为:在svr4中,当没有控制终端的会话头进程打开终端设备时(这个终端现在不是其他会话的控制终端),该终端自动成为这个会话头的控制终端。根据这个特点,如果没有第3步,那么第一次fork的子进程在调用setsid()创建一个新的会话之后,会成为这个会话组的组长即会话头,那么这个子进程就很可能在以后获得控制终端。加入了第3步之后,在子进程在创建一个子进程,孙子进程。孙子进程就不是子进程创建的会话的会话头,因此就不会再获得终端。

       在练习中发现:虽然我加入了2中的代码将keymngserver进程变成了守护进程,但是却发现keymngserver中的printf仍然可以输出到启动keymngserver的终端。这可能是因为孙子进程中的文件描述符是从父进程中复制过来的,因此孙子进程(守护进程)拥有启动keymngserver的终端的描述符,所以可以输出到启动keymngserver的终端。当启动keymngserver的终端关闭之后,孙子进程(守护进程)还在后台运行,但是就无法再输出到终端了。

以下是一些结果:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值