我最近在阅读this document中列出了一些可以用来实现socket服务器的策略。即:
为多个客户机提供每个线程,并使用非阻塞I/O和级别触发的就绪通知
为多个客户机提供每个线程,并使用非阻塞I/O和就绪更改通知
为多个客户机提供每个服务器线程,并使用异步I/O
为每个服务器线程提供一个客户机,并使用阻塞I/O
将服务器代码构建到内核中
现在,我想知道在cpython中应该使用哪一个,我们知道它有一些优点,也有一些缺点。我主要对高并发性下的性能感兴趣,是的,当前的一些实现速度太慢。
所以,如果我从简单的开始,“5”就不存在了,因为我不会将任何东西入侵内核。
“4”也似乎是因为金边而被淘汰。当然,您可以在这里使用多处理来代替线程,这确实大大提高了性能。阻塞IO还具有易于理解的优点。
在这里,我的知识有所减少:
“1”是传统的选择或轮询,可以与多处理进行细微的组合。
“2”是更新的epoll和kqueue使用的就绪更改通知
“3”我不确定是否有任何内核实现具有Python包装器。
所以,在python中,我们有一包像twisted这样的伟大工具。也许他们是一个更好的方法,虽然我有基准扭曲和发现它太慢的多处理器机器。我不知道,也许有4个带负载均衡器的扭杆就可以了。任何建议都将不胜感激。

最佳答案

asyncore基本上是“1”-它在内部使用select并且您只有一个线程来处理所有请求。根据文档,它还可以使用poll。(编辑:删除了扭曲的引用,我以为它使用了异步,但我错了)。
“2”可以用python-epoll实现(只需在谷歌上搜索它-以前从未见过)。
编辑:(来自注释)在python 2.6中,select module有epoll、kqueue和kevent内置(在支持的平台上)。所以您不需要任何外部库来执行边缘触发服务。
不要排除“4”,因为当线程实际执行或等待IO操作时(可能大多数时间),gil将被丢弃。当然,如果你有大量的联系,这是没有意义的。如果您有很多处理工作要做,那么Python可能对这些方案中的任何一个都没有意义。
关于灵活性,请看Twisted
实际上,您的问题归根结底就是要为请求做多少处理。如果您有大量的处理,并且需要利用多核并行操作,那么您可能需要多个进程。另一方面,如果您只需要监听大量连接,那么选择或epoll,使用少量线程就可以了。

07-28 02:11
查看更多