如何使用模块调用用户自定义函数在p中

2024-03-29 04:38:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经编写了一个irc bot,它运行一些命令,这些命令是预定义的python函数,将在运行bot的服务器上调用这些函数。在

我必须在不知道它们到底要做什么的情况下调用这些函数 (更多的I/O或一些计算开销大的东西,因为我在接受它们时会检查它们),但我需要获得它们的返回值,以便向irc通道作出答复。在

您推荐哪个模块并行运行这些回调?为什么?在

threading或{}模块,还有什么?在

我不知道我的协议是如何运作的,但我不知道从目前的角度来看,它是如何扭曲的。在

另外,由于我希望bot易于扩展,所以不需要命令异步执行任务。在


Tags: 模块函数命令服务器协议ircbot情况
2条回答

您的问题没有明确的答案:这实际上取决于函数的作用、调用频率以及需要的并行级别。在

threading和{}模块的工作方式截然不同。在

threading在Python解释器中实现本机线程:创建起来相当便宜,但由于Python的全局解释器锁(GIL),并行性受到限制。线程共享相同的地址空间,因此可能会相互干扰(例如,如果一个线程导致解释器崩溃,所有线程,包括你的应用程序,死亡),但线程间的通信是廉价和快速的结果。在

multiprocessing使用不同的进程实现并行:设置的开销远远高于线程(需要创建新进程),但每个进程都运行自己的解释器副本(因此没有GIL相关的锁定问题)并在不同的地址空间运行(隔离主应用程序)。子进程通过IPC通道与父进程进行通信,并要求对Python对象进行pickle/unpickle—同样,这比线程开销更大。在

你需要找出什么样的权衡最适合你的目的。在

<1),太长了,读不下去了;

如果您使用的是3.2+,请使用^{},如果您使用的是2.x版本,则使用PyPI上的^{}模块,该模块会反向移植相同的东西

您可以用^{}编写代码,并将其转换为^{},这是一行代码更改。而且API非常简单,没有什么可以混淆的。在


Also requiring the commands to do things asynchronously is not an option since I want the bot to be easily extensible.

我不明白这是怎么回事。异步代码的可扩展性并不差。当然,为了扩展异步代码,您必须知道如何编写异步代码,但是成千上万的初级JS程序员每天都在做一项几乎可以通过的工作,Python使它变得更加容易(参见^{}^{}in twistedtulip等)。另外,你在描述中明确地把这些事情称为“回调”,这意味着你已经在用这些术语思考了

如果您确信这实际上是一个需求,那么twisted是不可接受的。但是^{}(和eventlet等)可能只是编写看起来完全同步的代码,并且它是异步运行的。在

下一步:

What module do you recommend for running several of these callbacks in parallel and why?

你真的需要并行运行它们吗(你可以利用多个内核同时运行多个CPU绑定的作业)、并发(一个长时间运行的作业不会阻塞其他作业),还是两者都不需要(只要这些作业完成,它们是并行的、交错的还是序列化的都无关紧要)?在

如果需要并行,则需要multiprocessing。真的没有办法解决这个问题;GIL将阻止您在一个进程中使用多个核心。在

如果只需要并发,可以使用threading或{}。进程可能意味着在Windows和Unix之间(甚至有时在Unix之间)可能意味着更大的开销和/或更大的可移植性问题,有时它会迫使您考虑如何传递数据,或者,如果必须的话,共享数据。另一方面,通过而不是强迫您考虑传递或共享数据,线程使意外创建争用和其他错误变得更容易。(关于权衡的更多信息,请参阅isedev的伟大答案。)

如果两者都不需要,可以使用gevent(或类似的东西)、threading或{}。您可以创建10000个绿色线程并在它们之间切换,就像创建几百个线程或进程一样简单,而且开销要少得多。但是,一个长时间运行的CPU绑定命令可能会使整个系统停滞。在


无论使用哪种方法,您都很可能希望使用一个greenlet、线程或进程池从队列中拉出命令(而不是为每个命令派生一个新的命令,或者构建更复杂的命令)。在

虽然multiprocessing内置了这样的东西,threading没有。(实际上,是基于threading的线程池,但它在multiprocessing中,而不是{}。而且它不是公共API的一部分。)

multiprocessing中有很多非常酷的东西,如果你需要,一定要用它。(也有一些第三方库,里面有更酷的东西,可以让复杂的用例变得更简单,或者做一些multiprocessing做不到的事情。)但是如果不是,那么futures就简单得多,用线程和进程测试同一个系统的能力是非常强大的(或者甚至在运行时做的很简单)不错。在

相关问题 更多 >