线程与事件循环 - 网络编程(语言不可知)

use*_*014 4 python events multithreading twisted

我正在编写一个简单的守护进程来接收来自N个移动设备的数据.设备将轮询服务器并将其所需的数据作为简单的JSON发送.在通用术语中,服务器将接收数据,然后用它"做东西".

我知道这个话题已被打过很多次,但我很难理解利弊.

在并发性和可伸缩性方面,线程或事件(在Python中认为Twisted)是否更适合这种情况?事件模型似乎更有意义,但我想轮询你们.数据进入 - >过程数据 - >等待更多数据.如果"做东西"是计算密集型的东西怎么办?如果"do stuff"非常密集(例如插入数据库),该怎么办?这会阻止事件循环吗?每种方法的优点和缺点是什么?

dan*_*ano 5

我只能在Python的上下文中回答,因为那是我的大多数经验所在.根据您选择的语言,答案实际上可能略有不同.例如,Python在并行化I/O密集型操作方面比CPU密集型操作要好得多.

扭曲,龙卷风,gevent等异步编程库非常适合并行处理大量I/O. 如果您的工作负载涉及许多客户端连接,执行轻型CPU操作和/或大量I/O操作(如数据库读/写),或者您的客户端正在建立主要用于I/O的长期连接(想想WebSockets),然后一个异步库将非常适合您.大多数Python异步库都有流行数据库的异步驱动程序,因此您可以在不阻塞事件循环的情况下与它们进行交互.

如果您的服务器将要进行大量CPU密集型工作,您仍然可以使用异步库,但必须了解每次进行CPU工作时,事件循环都将被阻止.没有其他客户能够做任何事情.但是,有办法解决这个问题.您可以使用线程/进程池来管理CPU工作,并且只是异步等待响应.但显然这会使您的实现变得复杂一点.

使用Python,使用线程实际上并没有因为CPU操作而给你带来太大的收益,因为在大多数情况下只有一个线程可以运行一段时间,所以你并没有真正获得拥有多核CPU的好处(google" Python GIL"了解更多信息".通过线程忽略特定于Python的问题,线程将让您完全避免"阻塞事件循环"问题,并且线程代码通常比异步代码更容易理解,特别是如果您不熟悉异步编程的工作方式.但是你还必须处理常见的线程问题(同步共享状态等),并且它们不能像许多客户端的异步I/O一样扩展(参见http://en.wikipedia.org/) wiki/C10k_problem)

这两种方法在生产中都非常成功地使用,因此您需要更好地决定哪种方法适合您的需求/偏好.