And*_*ner 3 python daemon gevent
所以我一直在尝试创建一个在后台运行服务器的进程,并使用守护进程启动它.所以我的代码是:
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()
Run Code Online (Sandbox Code Playgroud)
但是,这给了我错误:
[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
Run Code Online (Sandbox Code Playgroud)
我在网上看了警告,我无法在任何地方找到它,错误并没有给我太多有用的信息.我运行了这里描述的程序/sf/answers/633313761/,我已经单独运行程序,只需将它放在main等等.但是,当我将它们组合起来时,它似乎搞乱了起来.有人知道为什么会这样吗?
你遇到了fork和epoll(或kqueue)之间不良交互的问题.通常,在fork之后很难使基于epoll的事件循环可靠地工作,并且最好重新创建一个新的事件循环.
有几种方法可以解决您的问题:
升级到gevent 1.0.与gevent 0.x不同,它在首次使用时创建事件循环,而不是在首次导入时创建,从而避免了问题.它也使用libev,它比libevent略微处理fork,尽管不是100%可靠.在你升级gevent后,你的问题很有可能消失.
延迟导入gevent包直到fork之后.