私はPython 2.7のasynchatとmailboxモジュールを使って電子メールサーバを書いています。 forgroundで走っているときは、すべてうまく動作し、長期間にわたって安定しています。ただし、デーモンとしてデタッチすると、メールボックスにアクセスすると、不正なファイル記述子のasyncore.loop()で例外が発生します。ファイルアクセスのみが問題です。ソケットI/Oは正常に動作し続けます。デーモンとしてデタッチされたときのファイルアクセスに関するasyncoreの例外
found_terminator()関数のファイルが__init__()
以降で開かれているかどうかは関係ありません。
私は、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がasyncoreチャンネルマップにどのように追加されるのか、close()の後にまだそこにある理由はわかりません
fdのどれが現在無効であるかは、私には明らかではありません。また、シェルプロセスで実行しているときにこれが起こらない理由も明確ではありません。
私はこの出来事を見ることができますが、私は、インポートモジュールを通して簡単に見てやったし、彼らは別のスレッドやプロセスを起動することを示すために何も表示されませんスレッディング使用した場合。また、誰にもドロップしないでルートとして実行し続けると、動作は変わりません。
他のデーモンでは、asyncoreモジュールとmailboxモジュールが使用されています。私は明らかな何かを見逃すはずです。