Monday, May 17, 2010

进程成为daemonize需要fork两次吗?

成为一个daemonize, 其实网上有很多例子, 也是可以使用的, 正如:
http://code.activestate.com/recipes/278731-creating-a-daemon-the-python-way/
里给出的例子。

但是, 我无法明白为什么要fork两次!, 下面是我的测试:

jessinio@jessinio-laptop:/tmp$ ps axj|head -n 1
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
jessinio@jessinio-laptop:/tmp$ ps axj|grep apache
   1  1820  1820  1820 ?           -1 Ss       0   0:10
/usr/sbin/apache2 -k start
 1820 16100  1820  1820 ?           -1 S     1000   0:00
/usr/sbin/apache2 -k start
 1820 16101  1820  1820 ?           -1 Sl    1000   0:00
/usr/sbin/apache2 -k start
 1820 16129  1820  1820 ?           -1 Sl    1000   0:00
/usr/sbin/apache2 -k start


可以中从得到这样的信息:
daemonize进程的PPID==1, PID==PGID==SID, 没有tty(为?)

如果这就是daemonize进程的要求的话, 请看我自己写的python代码:

if __name__ == "__main__":
   pid = os.fork()
   # child process
   if pid == 0:
       os.setsid()
       time.sleep(10)
   else:
       print 'parent %s, child %s' % (os.getpid(), pid)
       os._exit(0)

其中只是调用了一次fork函数。下面是它的运行結果:

jessinio@jessinio-laptop:/tmp$ ps axj|head -n 1
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
jessinio@jessinio-laptop:/tmp$ python process.py
parent 26117, child 26118
jessinio@jessinio-laptop:/tmp$ ps axj|grep process
   1 26118 26118 26118 ?           -1 Ss    1000   0:00 python process.py


可以看到, PPID==1, PID==PGID==SID, 没有tty

这是否可以认为: 只fork一次, 然后调用setsid就可以成为daemonize进程了呢?

在众多不解的情况下, 决定好好看看圣经: APUE 一书.

也很高兴, 从中找到了一点信息:

under system v-based systems, some people recommend calling fork again at this point and having the parent terminate, the second child continues as the daemon, This guarantees that the daemon is not a session leader , which prevents it from acquiring a controlling terminal under the system v rules. alternatively, to avoid acquiring a controlling terminal, be sure to specify O_NOCTTY whenever opening a terminal device.

fork第二次是防止被在打开一个terminal device时被系统分配到controlling terminal

只要不乱open(或者使用O_NOCTTY是不需要fork第二次的.

话又说回来, linux是怎么分配controlling terminal的呢?

APUE在这里没有提到linux, 只是提到了BSD和system-V的不同. 搜了一下, linux和BSD是一样的, 使用ioctl得到controlling terminal, URL: http://linux.die.net/man/4/tty_ioctl
如下引用:

TIOCSCTTY int
arg Make the given tty the controlling tty of the current process.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.