3

そのため、サーバーをバックグラウンドで実行するプロセスを作成し、デーモンプロセスで開始しようとしています。だから私のコードは:

class App():
  def __init__(self):
    self.stdin_path = '/dev/null'
    self.stdout_path = '/dev/tty'
    self.stderr_path = '/dev/tty'
    self.pidfile_path = '/tmp/foo.pid'
    self.pidfile_timeout = 5
  def run(self):
    server = WSGIServer(('localhost',28080),handle_request)
    server.serve_forever()

if __name__ == '__main__':
  app = App()
  daemon_runner = runner.DaemonRunner(app)
  daemon_runner.do_action()

ただし、これによりエラーが発生します。

[warn] Epoll ADD(1) on fd 5 failed.  Old events were 0; read change was 1 (add); write change was 0 (none): Invalid argument
Traceback (most recent call last):
  File "enrollmentrunner2.py", line 110, in <module>
    daemon_runner.do_action()
  File "/usr/lib/python2.7/dist-packages/daemon/runner.py", line 186, in do_action
    func(self)
  File "/usr/lib/python2.7/dist-packages/daemon/runner.py", line 131, in _start
    self.app.run()
  File "enrollmentrunner2.py", line 105, in run
    server.serve_forever()
  File "/usr/lib/python2.7/dist-packages/gevent/baseserver.py", line 188, in serve_forever
    self.start()
  File "/usr/lib/python2.7/dist-packages/gevent/baseserver.py", line 149, in start
    self.start_accepting()
  File "/usr/lib/python2.7/dist-packages/gevent/server.py", line 99, in start_accepting
    self._accept_event = core.read_event(self.socket.fileno(), self._do_accept, persist=True)
  File "core.pyx", line 308, in gevent.core.read_event.__init__ (gevent/core.c:3960)
  File "core.pyx", line 252, in gevent.core.event.add (gevent/core.c:2952)
IOError: [Errno 22] Invalid argument

オンラインで警告を探しましたが、どこにも見つかりませんでした。エラーによって、あまり役立つ情報が得られませんでした。ここで説明されているプログラムhttps://stackoverflow.com/a/9047339を実行し、メインなどに配置するだけでプログラムを単独で実行しました。ただし、それらを組み合わせると、混乱するようです。上。なぜこれが起こるのか誰かが知っていますか?

4

1 に答える 1

7

fork と epoll (または kqueue) の間の不適切な相互作用の問題にぶつかります。一般に、epoll ベースのイベント ループを fork 後に確実に動作させるのは難しく、新しいイベント ループを再作成するのが最善です。

問題を解決するにはいくつかの方法があります。

  • gevent 1.0 にアップグレードします。gevent 0.x とは異なり、最初にインポートしたときではなく、最初に使用したときにイベント ループが作成されるため、問題が回避されます。また、100% 信頼できるわけではありませんが、libevent よりもわずかにフォークをうまく処理する libev も使用します。gevent をアップグレードしただけで、問題が解決する可能性は十分にあります。

  • fork 後まで gevent パッケージのインポートを遅らせます。

于 2012-07-27T11:59:47.053 に答える