我已经编写了一个irc bot,它运行一些命令,这些命令是预定义的python函数,将在运行bot的服务器上调用这些函数。在
我必须在不知道它们到底要做什么的情况下调用这些函数
(更多的I/O或一些计算开销大的东西,因为我在接受它们时会检查它们),但我需要获得它们的返回值,以便向irc通道作出答复。在
您推荐哪个模块并行运行这些回调?为什么?在
threading
或{}模块,还有什么?在
我不知道我的协议是如何运作的,但我不知道从目前的角度来看,它是如何扭曲的。在
另外,由于我希望bot易于扩展,所以不需要命令异步执行任务。在
Tags:
您的问题没有明确的答案:这实际上取决于函数的作用、调用频率以及需要的并行级别。在
threading
和{threading
在Python解释器中实现本机线程:创建起来相当便宜,但由于Python的全局解释器锁(GIL),并行性受到限制。线程共享相同的地址空间,因此可能会相互干扰(例如,如果一个线程导致解释器崩溃,所有线程,包括你的应用程序,死亡),但线程间的通信是廉价和快速的结果。在multiprocessing
使用不同的进程实现并行:设置的开销远远高于线程(需要创建新进程),但每个进程都运行自己的解释器副本(因此没有GIL相关的锁定问题)并在不同的地址空间运行(隔离主应用程序)。子进程通过IPC通道与父进程进行通信,并要求对Python对象进行pickle/unpickle—同样,这比线程开销更大。在你需要找出什么样的权衡最适合你的目的。在
如果您使用的是3.2+,请使用^{} ,如果您使用的是2.x版本,则使用PyPI上的^{} 模块,该模块会反向移植相同的东西
您可以用^{} 编写代码,并将其转换为^{} ,这是一行代码更改。而且API非常简单,没有什么可以混淆的。在
我不明白这是怎么回事。异步代码的可扩展性并不差。当然,为了扩展异步代码,您必须知道如何编写异步代码,但是成千上万的初级JS程序员每天都在做一项几乎可以通过的工作,Python使它变得更加容易(参见^{} ,^{} in
twisted
,tulip
等)。另外,你在描述中明确地把这些事情称为“回调”,这意味着你已经在用这些术语思考了如果您确信这实际上是一个需求,那么} (和
twisted
是不可接受的。但是^{eventlet
等)可能只是编写看起来完全同步的代码,并且它是异步运行的。在下一步:
你真的需要并行运行它们吗(你可以利用多个内核同时运行多个CPU绑定的作业)、并发(一个长时间运行的作业不会阻塞其他作业),还是两者都不需要(只要这些作业完成,它们是并行的、交错的还是序列化的都无关紧要)?在
如果需要并行,则需要
multiprocessing
。真的没有办法解决这个问题;GIL将阻止您在一个进程中使用多个核心。在如果只需要并发,可以使用}。进程可能意味着在Windows和Unix之间(甚至有时在Unix之间)可能意味着更大的开销和/或更大的可移植性问题,有时它会迫使您考虑如何传递数据,或者,如果必须的话,共享数据。另一方面,通过而不是强迫您考虑传递或共享数据,线程使意外创建争用和其他错误变得更容易。(关于权衡的更多信息,请参阅isedev的伟大答案。)
threading
或{如果两者都不需要,可以使用}。您可以创建10000个绿色线程并在它们之间切换,就像创建几百个线程或进程一样简单,而且开销要少得多。但是,一个长时间运行的CPU绑定命令可能会使整个系统停滞。在
gevent
(或类似的东西)、threading
或{无论使用哪种方法,您都很可能希望使用一个greenlet、线程或进程池从队列中拉出命令(而不是为每个命令派生一个新的命令,或者构建更复杂的命令)。在
虽然}。而且它不是公共API的一部分。)
multiprocessing
内置了这样的东西,threading
没有。(实际上,是基于threading
的线程池,但它在multiprocessing
中,而不是{在
multiprocessing
中有很多非常酷的东西,如果你需要,一定要用它。(也有一些第三方库,里面有更酷的东西,可以让复杂的用例变得更简单,或者做一些multiprocessing
做不到的事情。)但是如果不是,那么futures
就简单得多,用线程和进程测试同一个系统的能力是非常强大的(或者甚至在运行时做的很简单)不错。在相关问题 更多 >
编程相关推荐