我最近阅读了这份文档,其中列出了可用于实现套接字服务器的一些策略.即,它们是:
为每个线程提供许多客户端,并使用非阻塞I/O和级别触发的就绪通知
为每个线程提供许多客户端,并使用非阻塞I/O和准备就绪更改通知
为每个服务器线程提供许多客户端,并使用异步I/O.
为每个服务器线程提供一个客户端,并使用阻塞I/O.
将服务器代码构建到内核中
现在,我将非常感谢CPython中应该使用的提示,我们知道它有一些好处和一些不好的地方.我最感兴趣的是高并发性下的性能,是的,当前的一些实现太慢了.
因此,如果我可以从容易的那个开始,"5"就出来了,因为我不会在内核中乱砍任何东西.
"4"看起来因为GIL而必须出局.当然,你可以在这里使用多处理来代替线程,这确实会带来显着的提升.阻止IO还具有易于理解的优点.
在这里,我的知识有所减弱:
"1"是传统的选择或民意调查,可以简单地与多处理相结合.
"2"是准备变更通知,由较新的epoll和kqueue使用
"3"我不确定是否有任何具有Python包装器的内核实现.
所以,在Python中我们有一大堆很棒的工具,比如Twisted.也许它们是一种更好的方法,虽然我已经对Twisted进行了基准测试,但在多处理器机器上发现它太慢了.我不知道,或许有4个带有负载平衡器的扭曲可能会这样做.任何意见,将不胜感激.
asyncore
基本上是"1" - 它在select
内部使用,你只有一个线程处理所有请求.根据文档,它也可以使用poll
.(编辑:删除Twisted参考,我认为它使用asyncore,但我错了).
"2"可能是用python-epoll实现的(只是谷歌搜索它 - 从未见过它).编辑:(来自评论)在python 2.6中,select模块有epoll,kqueue和kevent内置(在支持的平台上).因此,您不需要任何外部库来执行边缘触发的服务.
不要排除"4",因为当线程实际执行或等待IO操作时GIL将被丢弃(大多数时候可能).如果你当然拥有大量的联系,那就没有意义了.如果你有很多处理要做,那么python可能对任何这些方案都没有意义.
为了灵活性,可以看看Twisted?
在实践中,您的问题归结为您将对请求执行多少处理.如果你有很多处理,并且需要利用多核并行操作,那么你可能需要多个进程.另一方面,如果你只需要监听大量的连接,那么选择或epoll,少量的线程应该工作.