调用daemon()和调用fork()、setsid()、fork()等方法有什么区别?

12

我一直在研究如何创建Unix守护进程,似乎有两种方法。搜索时出现的冗长方法是调用fork()setsid(),再次调用fork(),使用chdir()切换到安全目录,设置umask(),最后关闭stdinstdoutstderr

然而,运行man daemon命令会显示一个daemon()函数的信息,它似乎做了以上所有相同的工作。这两种方法之间是否有任何区别,或者daemon()只是一个方便的函数,可以执行与冗长方法相同的操作?对于初学者的C程序员来说,哪种方法更好呢?

3个回答

20

daemon函数在POSIX标准中未定义,因此其实现(如果有的话)可能在不同平台上表现不同。

在Linux上使用glibc时,daemon只进行一次fork操作,可选地chdir(但只能到/,无法指定路径),不会更改umask,也不会关闭std*描述符(但可以选择将它们重新打开到/dev/null)。(源代码)

因此,它取决于平台,至少有一个实现比你所做的功能要少。如果您需要您正在执行的所有操作,请坚持使用该方法(或坚持使用daemon函数完全执行这些操作的平台)。


11
将文件描述符0、1和2保持开放并重定向到/dev/null比关闭它们更可取,因为否则你的守护进程打开的下一个文件(如日志文件、套接字等)将获得这些文件描述符。当你调用某些库来写入错误到标准错误流时,这可能会给你带来麻烦。 - caf
不关闭文件描述符0、1和2是个明智的决定。 - luis.espinal

2
请注意,daemon函数不符合任何标准。更好的做法是使用符合标准的函数(如POSIX定义的forksetsid)。

1

守护进程调用总结了冗长的 fork 过程,我不记得有任何实现会做更多的事情。

由于 daemon() 是一个高级概念,因此对于初学者和有经验的程序员来说,这绝对是首选。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接