【问题标题】:Exception in asyncore on file access when detached as daemon作为守护进程分离时文件访问的异步异常
【发布时间】:2016-05-06 22:06:11
【问题描述】:

我使用 Python 2.7 中的 asynchat 和邮箱模块编写了一个电子邮件服务器。在前台运行时,一切正常,并且在长时间的测试中保持稳定。但是,当作为守护程序分离时,对邮箱的访问会导致 asyncore.loop() 中出现错误文件描述符的异常。只有文件访问是一个问题。 Socket I/O 继续正常工作。

文件是在__init__() 中打开还是在found_terminator() 函数中打开似乎并不重要。

我正在使用 Schroeder 的 ActiveState 配方 278731 中的代码分离进程,但使用单独的守护程序模块不会改变症状。

这里有一段伪代码来展示流程:

createDaemon()
s = myServer() # subclass of asynchat.async_chat
dropPermissions #setuid nobody
asyncore.loop()

这是发生故障时的 strace 输出:

open("/tmp/MailboxDir/cur/1462562219.M374224P24795Q1.i7", O_RDONLY|O_LARGEFILE) = 8
fstat64(8, {st_mode=S_IFREG|0644, st_size=36, ...}) = 0
...
...
read(8, "To: you\nFrom: me\nSubject: test\n\n"..., 8192) = 36
read(8, "", 4096)                       = 0
read(8, "", 8192)                       = 0
close(8)                                = 0
...
stat64("/tmp/MailboxDir/cur/1462562219.M374224P24795Q1.i7", {st_mode=S_IFREG|0644, st_size=36, ...}) = 0
send(7, "+OK POP3 server ready\r\n", 23, 0) = 23
select(8, [4 5 6 7], [], [4 5 6 7], {30, 0}) = -1 EBADF (Bad file descriptor)

省略的部分涉及加载 parser.py 和 feedparser.py 模块,它们本身使用 mmap2 打开和关闭多个文件描述符。

因此电子邮件文件的 fd 已关闭 但不久之后,该 fd 显示在选择列表中。我不清楚 fd 是如何添加到异步通道映射中的,或者为什么它在 close() 之后仍然存在。我不清楚哪个 fd 现在无效。也不清楚为什么在 shell 进程中运行时不会发生这种情况。

如果我使用线程,我可以看到这种情况,但我快速浏览了导入的模块,没有看到任何表明它们启动了单独的线程或进程的信息。此外,如果我继续以 root 身份运行而不是丢给任何人,行为也不会改变。

asyncore 和mailbox 模块肯定会在其他守护进程中使用。我觉得我一定遗漏了一些明显的东西。

【问题讨论】:

    标签: python asyncore python-daemon


    【解决方案1】:

    事实证明,电子邮件包正在关闭文件描述符 4,无论它是否拥有它。在我的例子中,fd 4 总是分配给日志文件。我通过打开一个分配了 fd 4 的文本文件进行验证,并将日志文件推送到 fd 5。在处理从邮箱读取的第一封电子邮件时,该文本文件 fd 被关闭。

    尝试调试电子邮件包占用了太多时间,所以我写了一个足以满足我需要的替代品,然后继续我的工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-26
      • 2023-03-02
      • 2011-04-06
      • 1970-01-01
      • 2021-01-04
      • 1970-01-01
      相关资源
      最近更新 更多