Python、Asyncore 和 fork
对于初学者来说,我将 Twisted 和 SocketServer 与 ForkMixIn、ThreadMixIn 一起使用,并尝试了“线程池”接收。
然而,我想在 Python 中做一些特别的事情。
一点背景。之前我用 C 语言编写了一个简单的 TCP 守护进程,它将绑定到套接字并侦听它,然后预分叉 X 次,然后将服务器套接字 desc 传递给所有分叉,每个人都会非常非常地接受客户端。
我检查了我非常喜欢的基于“选择/轮询”的 asyncore。我唯一的不满是,我可以通过几次分叉来释放一点 CPU,以利用多 CPU 机器,并希望通过调度获得最佳效果。
我无法让它为我的一生服务。只有 1 个实例可以接受连接,所有其他实例只是在处理连接时抛出异常,“无法迭代空”。
这可行吗?我检查了很多,但我找不到任何用于分叉 asyncore 调度程序的代码(哭)
谢谢!
更新 1:(根据要求进行完整回溯)
error: uncaptured python exception, closing channel <__main__.EchoServer listening 0.0.0.0:8001 at 0x2ad4880c93f8> (<type 'exceptions.TypeError'>:'NoneType' /python2.6/asyncore.py|readwrite|99] [/usr/local/python2.6.9/lib/python2.6/asyncore.py|handle_read_event|408] [./6py-server.py|handle_accept|87])
始终发生在接受中,无论我是否在 asyncore.loop 之前分叉等。
更新 2:(完整源代码) 粘贴源
Just for starters, I used Twisted and SocketServer with both ForkMixIn, ThreadMixIn and tried the "thread-pool" recepies.
However, I wanted to make something particular work in Python.
Alittle background. Previously I wrote in C a simple TCP deamon that would bind to a socket and listen on it, then pre-fork X many times and then just pass the serversocket desc to all the forks and everyone would accept the clients very very marrily.
I checked out the "select/poll" based asyncore which I like alot. My only beef was that I could get a little CPU unbound by forking a few times to take advantage of the multi-cpu machine and hope for the best with scheduling.
I cant make it work for the life of me. Only 1 single instance can accept connections, all others simply throw an exception on handling the connect, 'can not iterate thru Empty'.
is this even feasible? I checked alot, but I couldnt find ANY code for forking asyncore dispatchers (cry)
Thank you!
Update 1: (Full traceback as requested)
error: uncaptured python exception, closing channel <__main__.EchoServer listening 0.0.0.0:8001 at 0x2ad4880c93f8> (<type 'exceptions.TypeError'>:'NoneType' /python2.6/asyncore.py|readwrite|99] [/usr/local/python2.6.9/lib/python2.6/asyncore.py|handle_read_event|408] [./6py-server.py|handle_accept|87])
Always happens in accept, regardless if I fork before the asyncore.loop, etc.
Update 2: (full source)
pastebined source
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您应该使用代码标记进行回溯,否则它会显示混乱并且我们看不到异常类型。
但我相信这是
TypeError: 'NoneType' object is not iterable
因为self.accept()
可以返回None
。原因是多个进程可以获取监听套接字的读事件,但只有一个进程可以接受该事件。其余进程将收到被捕获的EWOULDBLOCK
错误,但随后它返回None
而不是连接地址对。将
handle_accept()
更改为在accept()
返回None
时立即返回。You should use code markup for traceback, otherwise it's displayed messed and we don't see exception type.
But I believe it's
TypeError: 'NoneType' object is not iterable
sinceself.accept()
can returnNone
. The reason is that several processes can get read event for listening socket, but only one can accept it. The rest processes will getEWOULDBLOCK
error which is caught, but then it returnsNone
instead of connection-address pair.Change your
handle_accept()
to return immediately whenaccept()
returnsNone
.