如何将两个整数与 Twisted 相加?

Posted

技术标签:

【中文标题】如何将两个整数与 Twisted 相加?【英文标题】:How do I add two integers together with Twisted? 【发布时间】:2011-11-10 22:36:29 【问题描述】:

我的程序中有两个整数;我们称它们为“a”和“b”。我想将它们加在一起并得到另一个整数。这些是常规的 Python int 对象。我很好奇;我如何将它们与 Twisted 一起添加?某处有特殊的performAsynchronousAddition 功能吗?我需要Deferred 吗?反应堆呢?是否涉及反应堆?

【问题讨论】:

你为什么不用a + b 不会“a + b”阻止吗? 由于a + b不是I/O,所以不会阻塞。执行需要一些时间,但您执行的任何其他操作也需要一些时间。 明确 a+b 确实会阻塞。如果 a 和 b 是足够大的整数怎么办?请记住,非阻塞通常意味着“阻塞非常短的时间”。 我认为您在这里使用的“块”与一般用法不一致。通常,当一个进程变得不可运行时,它被描述为“阻塞”,等待一些外部事件(例如网络传输结束)。 a+b 作为一个普通的算术运算永远不会阻塞 - 它只会使用 CPU 直到它完成,所以运行它的进程/线程将始终保持可运行。 【参考方案1】:

好的,说清楚。

Twisted 没有对 cpu bound tasks 做任何事情,这是有充分理由的。没有办法通过重新排序子任务来使计算绑定的工作更快;你唯一能做的就是增加更多的计算资源;甚至在 python 中也行不通,因为它的实现很微妙。

Twisted 提供了特殊的语义和事件循环处理,以防程序“卡住”在它控制的情况下等待外部的东西;通常是在另一台机器上运行并通过网络连接与您的扭曲进程通信的进程。由于您无论如何都会等待,因此twisted 为您提供了一种同时完成更多事情的机制。也就是说twisted为I/O Bound tasks

提供并发

tl;dr:twisted 用于网络代码。其他一切都只是普通的python。

【讨论】:

(值得注意的是,对于spawnProcess,Twisted 确实为 CPU 绑定任务提供了一点支持,通过将它们转换为 I/O 绑定任务然后进行通信以同样的方式处理它们。但这仍然是一个很好的解释。) 作为朋友和邻居,我求你了:请不要为了两个整数相加而产生进程。 很诱人,因为它是为了进一步吸引你,我应该指出,我是 Twisted 的原作者,这个问题是作为一种实验而写的。我们收到了很多类似的问题:“我如何使用 Twisted 调用函数 X?”,其中答案(“X()”)非常明显,以至于我们无法传达它。许多程序员太习惯于使用像“time.sleep()”这样的习语来表示“......然后做一堆 I/O 和/或计算......”他们不能或不会充实他们的例子此外,当 I/O 和计算之间的区别非常关键时。 我实际上非常喜欢您的回答,并且将来可能会使用其中的元素。我很惊讶这么快就得到了如此有用的反馈;)。【参考方案2】:

这个怎么样:

c = a + b

这应该可以,并且不需要异步完成(非常快)。

【讨论】:

您忘记了 Python 整数是未绑定的。构建任何操作都需要 分钟 的数字非常容易。 查看原始问题的 cmets【参考方案3】:

好问题,Twisted(或 Python)应该有办法至少生成多个内核的“a + b”(在我的 8 核 i7 上)。

不幸的是,Python GIL 阻止了这种情况的发生,这意味着您将不得不等待,不仅是 CPU 密集型任务,还有一个核心在完成这项工作,而其他七个核心什么也不做。

注意:也许更好的例子是“a() + b()”,甚至是“fact(sqrt(a()**b())”等,但重要的事实是上面的操作会锁定一个核心和 GIL 几乎阻止 Python 在该操作期间执行任何其他操作,这可能是几个毫秒...

【讨论】:

-1: a + b 是否在单个或多个 CPU 上运行取决于 ab 是什么 例如,如果 a 和 @987654325 可以释放 GIL @ 是 numpy 数组。该任务可能是令人尴尬的并行,即在多个 CPU 之间分配它是微不足道的。结果可能比顺序变体慢,但可以轻松完成。 由于 GIL,不可能在同一个 CPU 和进程中的多个内核之间分配处理。因此,即使我的全新 MBP 中有 8 个内核并启动 8 个线程来分配计算,性能也会降低 1000 倍或更多。 可以在同一个进程中跨多个 CPU 内核分配处理,因为 GIL 可以在 C 扩展中发布,例如 numpylxmlregex 等。 我知道有一些解决方法,但是如果你只是想在“纯”Python 中启动 8 个线程并让它们在每个核心上提前一个,可能通过一些锁来协调进度,你不走运... 可能有点晚了,但是看看 Pony 语言,它有一个 actor 关键字,表示异步类/对象。 Pony 将为 CPU 上的每个内核启动一个线程,这可能使相同的程序在 16 核 CPU 上运行(几乎)速度是在 8 核上运行的两倍。我希望我可以在 Python 中做同样的事情,但 GIL 阻止了它。 (不过,它确实适用于 GIL'less Jython 和 IronPython)

以上是关于如何将两个整数与 Twisted 相加?的主要内容,如果未能解决你的问题,请参考以下文章

twisted(转)

如何在Twisted框架中采用两个路径变量?

如何将结构化数据从 Twisted 发送到 syslog?

Twisted 有啥了不起的? [关闭]

Twisted reactor 如何与基于试验的单元测试一起工作?

Python:如何使用 Twisted 作为 SUDS 的传输方式?