我正在为教育目的编写HTTP代理服务器。在这个服务器中,我希望从使用多个处理器内核中受益,因为有些任务显然可以并行完成。
我们有0到5个HTTP请求处理步骤,每个步骤对应1或2个IO操作。步骤描述非常简单,可以在图表中看到。并行实现的想法如下:
1“监听”方法只需倾听 s套接字和接受的传入连接
2“调度程序”方法:
- 等待选择功能,让fds可用于进一步分配
- 将可用的fds(连接)输入到RequestSet中。也许将它称为TaskSet会更好,因为任务在读取HTTP请求之前出现。每项任务至少都有 [当前fd(每一步可能会改变);步数;]
- 安排每个步骤处理(见3),改变每个请求的当前步骤
- 根据当前步骤打开/关闭fds,指定要请求的fds
3“进程”方法应用于执行每个步骤(发送数据)的每个请求
我想在单独的线程中创建(1)和(2),因为它们意味着阻止“listen”和“select”。 将每个请求及其当前步骤(3)发送到一个单独的线程,直到处理器核心数量(作为参数传递)。动机是每个套接字操作都在一个单独的缓冲区上执行,并且可以并行完成。
两个问题:
- 这一切都有意义吗?
-am我是正确的,如果在Python中实现,我应该使用Python实现(如IronPython)而不使用GIL。使用常规CPython我不会受益于同时recv / write的几个核心(虽然在被阻止时仍能正确利用时间)?
答案 0 :(得分:1)
我建议教育项目的这些步骤。
在multiprocessing
模块中,阅读Pool
。您可能想要创建一个工作池,其大小与CPU的数量成比例(cpu_count()
为multiprocessing.Queue
)。
阅读this question,特别是multiprocessing.Manager
和Queue
。您可能希望创建一个Manager
并将其传递给所有池工作者。
在单个进程中创建Queue
,Pool
和accept
,循环和Queue
传入连接后。将每个已接受的连接推送到get
。每个池工作者都应该循环Queue
来自此Visual Studio
的连接(这将阻止它们,而没有连接)。当工人找到这样的连接时,它应该进一步处理它。
这样可以更好地利用您的核心。
注意在页面中有一个很好的exchanging data between processes - 搜索“一个示例,说明在共享单个侦听套接字时,每个工作进程池如何运行SimpleHTTPServer.HttpServer实例。“)