Python:守护进程时关闭文件描述符

3 投票
1 回答
3718 浏览
提问于 2025-04-17 16:37

我在我的应用程序中有这段代码:

def daemonize_process(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
'''
Fork the current process as a daemon (background process), redirecting
standard file descriptors

@param string stdin standard input file name
@param string stdout standard output file name
@param string stderr standard error file name
'''

# To transform a process in a daemon, it is necessary to fork, decouple from
# parent environment, fork again and close all opened file descriptors.

# do first fork
try:
    pid = os.fork()
    if pid > 0:
        # exit from first parent process
        # using os._exit() instead of sys.exit() in a child process after
        # a fork is recommended by Python API docs
        os._exit(0)
except OSError as e:
    sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror))
    sys.exit(1)

# decouple from parent environment
os.chdir("/")
os.umask(0)
os.setsid()

# do second fork
try:
    pid = os.fork()
    if pid > 0:
        # exit from second parent process
        # using os._exit() instead of sys.exit() in a child process after
        # a fork is recommended by Python API docs
        os._exit(0)
except OSError, e:
    sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror))
    sys.exit(1)

# close all file descriptors
import resource
maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
if (maxfd == resource.RLIM_INFINITY):
    maxfd = 1024

for fd in range(0, maxfd):
    try:
        os.close(fd)
    except OSError:
        sys.stderr.write("error closing file: (%d) %s\n" % (e.errno, e.strerror))
        pass

# process is now daemonized, redirect standard file descriptors.
for f in sys.stdout, sys.stderr:
    f.flush( )
si = file(stdin, 'r')
so = file(stdout, 'a+')
se = file(stderr, 'a+', 0)
os.dup2(si.fileno( ), sys.stdin.fileno( ))
os.dup2(so.fileno( ), sys.stdout.fileno( ))
os.dup2(se.fileno( ), sys.stderr.fileno( ))

在我在网上看到的守护进程代码中,子进程没有关闭文件描述符。我为什么要这样做呢?我觉得我可能还想继续使用在分叉(fork)之前就已经在用的文件。

提前谢谢你。

1 个回答

1

为什么要关闭文件描述符呢?一般来说,你可以认为启动你这个后台程序的进程是知道自己在做什么的,它会在执行新的程序之前关闭自己的文件描述符。

举个例子,如果你从bash(一个命令行工具)运行程序,你得到的打开的文件描述符通常只有标准的几个,加上你在命令行手动设置的重定向。

如果一个程序不把文件描述符关掉,那它就是有问题的。其实也可以使用FD_CLOEXEC这个选项来打开文件,这样在执行新的程序时,它们会自动被关闭。

撰写回答