Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用Python编写基于套接字的服务器,推荐的策略?_Python_Sockets_Asynchronous_Network Programming_C10k - Fatal编程技术网

用Python编写基于套接字的服务器,推荐的策略?

用Python编写基于套接字的服务器,推荐的策略?,python,sockets,asynchronous,network-programming,c10k,Python,Sockets,Asynchronous,Network Programming,C10k,我最近读了一篇文章,其中列出了一些可以用来实现套接字服务器的策略。即: 使用每个线程为多个客户端提供服务,并使用非阻塞I/O和级别触发就绪通知 使用每个线程为多个客户端提供服务,并使用非阻塞I/O和就绪更改通知 使用每个服务器线程为多个客户端提供服务,并使用异步I/O 为每个服务器线程提供一个客户端,并使用阻塞I/O 将服务器代码构建到内核中 现在,我希望您能给我一个提示,在CPython中应该使用哪个,我们知道它有一些优点,也有一些缺点。我最感兴趣的是高并发下的性能,是的,当前的许多实现都太慢

我最近读了一篇文章,其中列出了一些可以用来实现套接字服务器的策略。即:

  • 使用每个线程为多个客户端提供服务,并使用非阻塞I/O和级别触发就绪通知
  • 使用每个线程为多个客户端提供服务,并使用非阻塞I/O和就绪更改通知
  • 使用每个服务器线程为多个客户端提供服务,并使用异步I/O
  • 为每个服务器线程提供一个客户端,并使用阻塞I/O
  • 将服务器代码构建到内核中
  • 现在,我希望您能给我一个提示,在CPython中应该使用哪个,我们知道它有一些优点,也有一些缺点。我最感兴趣的是高并发下的性能,是的,当前的许多实现都太慢了

    因此,如果我可以从简单的一个开始,那么“5”就不存在了,因为我不会对内核进行任何黑客攻击

    “4”看起来也一定是因为GIL而出局了。当然,您可以在这里使用多处理来代替线程,这确实大大提高了性能。阻塞IO还有易于理解的优点

    在这里,我的知识有点衰退:

    “1”是传统的选择或轮询,可以与多处理简单地结合起来

    “2”是准备就绪更改通知,由较新的epoll和kqueue使用

    “3”我不确定是否有任何具有Python包装器的内核实现

    因此,在Python中,我们有很多很棒的工具,比如Twisted。也许它们是一种更好的方法,尽管我已经对Twisted进行了基准测试,发现它在多处理器机器上太慢了。也许使用负载平衡器进行4次扭曲就可以了,我不知道。任何建议都将不胜感激。

    对于多处理器(多核)机器。有了CPython,每个核心至少需要一个进程才能扩展。正如您所说,您需要CPython,您可以尝试使用
    ForkingMixIn
    对其进行基准测试。使用Linux2.6可能会得到一些有趣的结果

    另一种方法是使用。那是。但我明白这并不总是可能的

    基本上是“1”-它在内部使用
    select
    ,只有一个线程处理所有请求。根据文档,它还可以使用
    轮询
    。(编辑:删除了Twisted引用,我认为它使用了asyncore,但我错了)

    “2”可能是通过实现的(只需在谷歌上搜索它-以前从未见过它)。 编辑:(来自注释)在Python2.6中,有epoll、kqueue和kevent内置(在支持的平台上)。因此,您不需要任何外部库来执行边缘触发服务

    不要排除“4”,因为当线程实际执行或等待IO操作时(可能大多数情况下),GIL将被删除。当然,如果你有大量的联系,这是没有意义的。如果您有很多处理要做,那么python可能对这些方案中的任何一个都没有意义

    关于灵活性,请看


    实际上,您的问题归结为您将对请求进行多少处理。如果您有大量的处理,并且需要利用多核并行操作,那么您可能需要多个进程。另一方面,如果你只需要监听大量的连接,那么选择或epoll,加上少量的线程就可以了。

    我喜欢道格拉斯的答案,但作为旁白

    您可以使用一个集中式调度线程/进程,该线程/进程使用和委托一组工作线程/来侦听准备就绪通知,以帮助实现并行性目标


    然而,正如Douglas所提到的,GIL不会在最长的I/O操作期间保持(因为没有Python API发生任何事情),因此如果您担心的是响应延迟,您可以尝试将代码的关键部分移动到CPython API。

    我可以建议其他链接吗

    是一个跨平台库,用于使用python 2.5中的增强生成器进行面向网络、基于协同路由的编程。在cogen项目的主页上,有几个类似目的的项目的链接。

    关于“fork”如何?(我假设这就是ForkingMixIn所做的)如果请求是在“无共享”(除DB或文件系统外)体系结构中处理的,那么fork()在大多数*nixes上启动得非常快,您不必担心线程带来的所有愚蠢的错误和复杂性

    IMHO说,线程是一种设计疾病,它是由具有过重进程的操作系统强加给我们的。克隆具有“写时复制”属性的页表似乎价格不高,尤其是在运行解释器的情况下

    很抱歉,我不能说得更具体了,但我更多的是一个Perl向Ruby程序员的过渡(当我在工作中没有为大量Java而忙碌时)


    更新:我终于在我的“空闲时间”里对线程和fork进行了一些计时。请查看:

    扩大: 一种解决方案是gevent。maries是greenlet实现的基于libevent的事件轮询和轻量级协作任务切换

    您得到的是事件系统的所有性能和可伸缩性,以及优雅而简单的阻塞IO编程模型


    (我不知道回答老问题的惯例是什么,但我决定还是加上我的2美分)

    谢谢,但你有没有对这些问题进行基准测试?他们很慢。如果不是必须的话,我不会发明轮子。我认为epoll在2.6+的标准库中,并且在2.5版本中易于安装。这个包名为select something。抱歉说得不清楚。Twisted也可以使用epoll。事实上,Twisted将所有受支持的事件通知API转换为一个统一的API,并提供给您。因此,如果平台能做的最好的事情就是选择,那么你的应用程序将使用选择。如果它有epoll,则您的应用程序使用epoll。对你来说都是透明的。@new123456,你说得对,没有人指出这一点