我必须编写一个可以检查多个(可能多达数百个)电子邮件帐户的新消息的小守护进程。
到目前为止我的想法:
我可以为每个连接创建一个新线程,使用imapclient每 x 秒检索一次消息,或者在可能的情况下使用 IMAP IDLE。我还可以稍微修改 imapclient 并且select()
仅使用单个线程激活 IMAP IDLE 的所有套接字。
有没有更好的方法来解决这个任务?
我必须编写一个可以检查多个(可能多达数百个)电子邮件帐户的新消息的小守护进程。
到目前为止我的想法:
我可以为每个连接创建一个新线程,使用imapclient每 x 秒检索一次消息,或者在可能的情况下使用 IMAP IDLE。我还可以稍微修改 imapclient 并且select()
仅使用单个线程激活 IMAP IDLE 的所有套接字。
有没有更好的方法来解决这个任务?
要是你几个月后问的话就好了,因为 Python 3.3.1 可能会有一个漂亮的新异步 API。有关当前原型,请参见http://code.google.com/p/tulip/,但您可能还不想使用它。
如果您在 Windows 上,您可能能够毫无问题地处理数百个线程。如果是这样,这可能是最简单的解决方案。所以,试试看。
如果您在 Unix 上,您可能想要使用poll
而不是select
,因为select
当您进入数百个连接时,扩展性很差。(epoll
在 linux 或kqueue
Mac/BSD 上的可扩展性更高,但在您进入数以千计的连接之前通常并不重要。)
但在您自己执行此操作之前,您可能需要考虑一些事项:
Twisted
绝对是其中最难进入的——但它还附带了一个准备就绪的 IMAP 客户端,以及其他数百种东西,所以如果你愿意处理一些学习曲线,你可能会做很多事情快点。
Tornado
感觉最喜欢写原生select
类型的代码。我实际上并不知道它附带的所有功能。它可能有一个 IMAP 客户端,但如果没有,您将采用imapclient
与select
.
Monocle
Twisted
位于or之上Tornado
,并允许您编写类似于 3.3.1 中的代码,在 Twisted 或 Tornado 之上(尽管实际上,您可以直接在 Twisted 中使用 来做同样的事情inlineCallbacks
,只是文档不鼓励您无需先学习其他所有内容即可学习)。再说一次,你会在imapclient
这里捣乱。(或者使用Twisted
's IMAP 客户端来代替......但在这一点上,您不妨Twisted
直接使用。)
gevent
让您编写与线程(或同步)代码几乎相同的代码,并且神奇地使其异步。您可能需要imapclient
稍微修改一下,但它可能就像运行神奇的猴子补丁实用程序一样简单,仅此而已。除此之外,您编写的代码与使用线程编写的代码相同,只是您创建了一堆greenlet而不是一堆线程,并且您获得了一个或两个数量级的可伸缩性。
如果您正在寻找绝对最大的可扩展性,您可能希望同时并行化和多路复用(例如,gevent
在 Unix 上运行 8 个进程,每个进程都使用 ,,或者在 Windows 上将本机线程池附加到 IOCP),但是对于几百个连接,这不是必需的。