我正在编写一个HTTP代理服务器,用于教育目的。在这个服务器中,我想从使用多处理器内核中获益,因为有一些任务显然可以并行完成。你知道吗
我们有0-5个HTTP请求处理步骤,每个步骤对应1或2个IO操作。步骤描述非常简单,可以在图表上看到。并行的想法如下:
1“listen”方法只是侦听一个套接字并接受传入的连接
2“调度器”方法:
-等待选择函数以获得可用于进一步分配的FD
-将可用的FD(连接)放入请求集中。也许最好将其称为TaskSet,因为任务出现在读取HTTP请求之前。每个任务至少有 [当前fd(每一步可能改变);步数;]
-安排每个步骤的处理(见3),更改每个请求的当前步骤
-根据当前步骤打开/关闭fds,将fds分配给请求
3“处理”方法应用于每个请求以执行每个步骤(发送数据)
我想把(1)和(2)分别放在一个单独的线程中,因为它们意味着阻塞“listen”和“select”。 将当前步骤为(3)的每个请求发送到一个单独的线程,最多为处理器核心数(作为参数传递)。其动机是,每个套接字操作都在一个单独的缓冲区上执行,并且可以并行完成。你知道吗
两个问题:
-这些都有意义吗?
-我说的对吗,如果用Python实现,我应该使用没有GIL的Python实现(比如IronPython)。使用常规的CPython,我不会从同时接收/写入的几个内核中获益(当被阻塞时仍然正确地利用时间)?你知道吗
我建议这些步骤用于教育项目。你知道吗
在} 。您可能想创建一个worker池,其大小与cpu的数量成正比(参见
multiprocessing
模块中,阅读^{cpu_count()
的this question)。阅读exchanging data between processes,特别是
multiprocessing.Queue
和multiprocessing.Manager
。您可能希望创建一个Queue
并将其传递给所有池工作线程。在创建
Manager
、Queue
和Pool
之后,在单个进程中循环和accept
传入连接。将每个接受的连接推送到Queue
。每个池工作线程都应该从这个Queue
循环和get
连接(这将在没有连接时阻止它们)。当工作进程发现这样的连接时,它应该进一步处理它。这将相对更好地利用你的核心。你知道吗
注意有一个非常好的example in the standard documentation-在页面中,搜索“一个工作进程池如何运行SimpleHTTPServer.HttpServer共享单个侦听套接字时的实例。“)
相关问题 更多 >
编程相关推荐