预处理多线程Python应用程序

预处理多线程Python应用程序,python,multithreading,architecture,gevent,preforking,Python,Multithreading,Architecture,Gevent,Preforking,我有一个已经是多线程的Python程序,我想用进程替换一些线程,以减少上下文切换并利用gevent进行异步I/O。 主进程是I/O绑定的,因此我想使用gevent来处理大量并发I/O。我们将其称为系统的接收器组件 程序的其余部分主要受CPU限制,因此我希望每个进程都有一些线程来处理来自接收器的请求。这些是我的工作进程。 我之所以选择线程在一个进程中处理多个请求,是因为创建和销毁线程的成本更低。如果程序接收到大量请求,它可以自动扩展以启动更多线程以处理更多请求。当负载降低时,它可以去掉额外的线程,

我有一个已经是多线程的Python程序,我想用进程替换一些线程,以减少上下文切换并利用gevent进行异步I/O。
主进程是I/O绑定的,因此我想使用gevent来处理大量并发I/O。我们将其称为系统的接收器组件

程序的其余部分主要受CPU限制,因此我希望每个进程都有一些线程来处理来自接收器的请求。这些是我的工作进程。
我之所以选择线程在一个进程中处理多个请求,是因为创建和销毁线程的成本更低。如果程序接收到大量请求,它可以自动扩展以启动更多线程以处理更多请求。当负载降低时,它可以去掉额外的线程,以避免上下文切换的额外开销

使用gevent进行分叉可能会导致一些问题,而存在这些问题正是为了解决这些问题。
工作线程有时确实从各种源(如缓存和数据库)读取数据,但如果我理解正确,当I/O发生时,GIL将切换到另一个线程

如果我决定在我的工作进程中使用gevent,我可以(我认为)避免修补线程模块,并为每个工作进程分配一个greenlet池。当I/O发生时,GIL是否仍然会被释放,并且当gevent与线程组合时,另一个线程将开始执行,直到I/O调用完成

最后还有另一个将响应保存到数据库的过程。它自然是I/O绑定的,因此gevent将是执行此操作的最佳选择

我已经读到了关于这个问题的报道。我不会在主进程中创建任何线程,因此不会将锁机制(如互斥锁)复制到子进程。我不打算分叉我的任何子进程。假设我在这个设计的任何阶段都没有遇到麻烦,安全吗?
Python是否减轻了预处理和线程的一些问题?

Python的GIL将阻止单个Python进程中的任何实际并发。因此,虽然您可以使用多线程或异步IO来处理每个工作者的大量请求,但要实现真正的并发性,您需要python的多处理包。您可能应该使用一个池,其中配置的max_requests_per_child为几百个左右的请求,并且必须注意实际进程的数量。如果您的任务对CPU来说真的很难,那么如果您没有剩余的内核来做“其他事情”,那么您可以暂停您的系统。但是,这只能通过实验来推断。

如果您的工作人员确实受到CPU的限制,那么线程绝对不是扩展的方式。因为吉尔。因此,在我看来,您的总体架构是反常的(或者更好地说是颠倒的),您可以使用线程作为接收器,因为它们会阻塞。通过gevent资源占用实现异步,但不会对性能产生太大影响。但是,您的工作人员应该是基于标准python库的多处理的。你可以预先分配几十个,因为如果你是100%的CPU限制,那么拥有比内核更多的进程是没有意义的。给它添加一些阻塞IO,所以添加一些进程。我知道GIL,但不像其他程序员那样害怕它。出于什么原因,您不将gevent用于仅I/O任务?自动缩放功能是我真正需要的一个功能,因为我们的工作负载不同。创建和销毁进程的成本要高得多。我不应该担心吗?我拥有的进程数和内核数一样多,这意味着我每次只能为每台服务器处理几个请求,这相当昂贵。还有,为什么要选择阻塞I/O而不是非阻塞I/O呢?好吧,你在这里自相矛盾:如果你的工作人员都是CPU受限的,那么你一定会害怕GIL。因为它有效地序列化了执行。这就是引入多处理模块的确切原因。关于阻塞/线程IO与非阻塞:我不是说你不应该使用gevent。但是AFAIK异步进程并不是什么灵丹妙药,它们所做的只是减少进程资源占用(减少内存),因为操作系统管理IO调度,而不是让线程坐在上面。与高负载场景相关。不知道你是否有一个更详细的说明:如果你的任务真的是100%的CPU限制,你如何想象你可以提供比你的内核数量更多的请求?这在物理上是不可能的。由于几乎没有什么东西是100%受CPU限制的,所以您可以有更多的进程来完成这项工作,但偶尔创建和重新创建它们并不是您的操作系统和整个应用程序将承受的负担。但是,如果您想要服务的请求多于您的核心,那么您需要一个计算机集群。再次与过程做繁重的提升。在C/C++/Java中,可以改用线程。但是,这里也应用了core#的限制。如果我以某种方式增强,是否意味着我将能够暂时使用多线程程序?现在重写它根本不值得我花时间。你很好地使用了你的程序——它是你的:)它不会并发。如果可以接受,由你决定。关于你的建议的可用性或不足之处,请阅读