1
117
按照复杂性增加的顺序: 使用 threading module赞成的意见:
欺骗:
使用 multiprocessing 单元
在简单的用例中,这与使用
赞成的意见:
欺骗:
使用事件模型,例如 Twisted赞成的意见:
欺骗:
在里面 全部的 我假设您已经了解了多任务处理涉及的许多问题,特别是如何在任务之间共享数据的棘手问题。如果出于某种原因,您不知道何时以及如何使用锁和条件,您必须从这些开始。多任务代码充满了微妙之处和陷阱,在开始之前最好对概念有一个很好的理解。 |
2
104
你已经得到了各种各样的答案,从“假线程”到外部框架,但我没看到有人提到
“忘记”共享内存,它被认为是线程与多处理的主要优势——它不能很好地工作,不能很好地扩展,从来没有,将来也不会。仅对设置一次的数据结构使用共享内存
之前
您生成了子线程,之后再也没有更改过——对于其他所有内容,请创建一个
仅有一个的
线程负责该资源,并通过
不要 在需要时生成线程,否则线程切换开销将使您无法承受。
两个线程之间的通信始终通过
每个管理单个资源(或小型内聚资源集)的专用线程侦听特定队列上的请求。队列实例。池中的线程在单个共享队列上等待 让你在这方面失败)。
您还可以使用队列“停放”资源实例,这些资源可由任何一个线程使用,但决不能在多个线程之间同时共享(与某些DBAPI组件的DB连接、与其他组件的游标等)——这允许您放宽专用线程的要求,以支持更多的池(从共享队列中获取需要可排队资源的请求的池线程将从apppropriate队列中获取该资源,如有必要,等待等)。 Twisted实际上是组织这种小步舞曲(或方块舞,视情况而定)的一种好方法,这不仅要归功于延迟,还要归功于其健全、坚实、高度可扩展的基础架构:只有在真正需要时,您才可以安排使用线程或子进程,虽然在单个事件驱动线程中执行大多数通常被认为是值得执行的任务。 但是,我意识到Twisted并不适合所有人——即使你不能完全理解异步事件驱动的方法,也可以使用“专用或共享资源,使用wazoo队列,从不做任何需要锁的事情,或者,Guido禁止,任何更高级的同步过程,如信号量或条件”的方法,与我偶然发现的任何其他广泛应用的线程方法相比,它仍将提供更高的可靠性和性能。 |
3
22
这取决于你想做什么,但我倾向于只使用
等等我经常使用由提供的同步队列设置生产者/消费者
|
4
13
Kamaelia 是一个python框架,用于构建具有大量通信进程的应用程序。 Twisted 和 Parallel Python 然后给出了卡迈利亚的实际演示。
Easy Concurrency with Kamaelia - Part 1
(59:08)
|
5
6
关于Kamaelia,上面的答案并没有真正涵盖这里的好处。Kamaelia的方法为处理线程、生成器和;在单个系统中处理并发性。
“不完美”部分是由于尚未为收件箱和发件箱添加语法糖(尽管这一点正在讨论中)-系统中的安全性/可用性是重点。 以上面使用裸线程的生产者-消费者为例,这在Kamaelia中变成了:
在本例中,不管这些是线程化组件还是其他组件,从使用角度来看,它们之间的唯一区别是组件的基类。生成器组件使用列表进行通信,线程组件使用队列。队列和基于进程的组件使用os.pipes进行通信。 然而,这种方法背后的原因是使调试困难的bug变得更加困难。在线程或任何共享内存并发中,您面临的首要问题是共享数据更新意外中断。通过使用消息传递,您可以消除 一 一类错误。 如果您在任何地方都使用裸线程和锁,那么您通常是在假设编写代码时不会犯任何错误的情况下工作的。虽然我们都渴望这样,但这种情况很少发生。通过将锁定行为封装在一个地方,可以简化可能出错的地方。(上下文处理程序有帮助,但不帮助上下文处理程序之外的意外更新) 显然,并不是每段代码都能以消息传递和共享的方式编写,这就是为什么Kamaelia也有一个简单的软件事务内存(STM),这是一个非常好的主意,有一个讨厌的名字——它更像是变量的版本控制——即检出一些变量,更新它们并提交回来。如果发生碰撞,请冲洗并重复。
无论如何,我希望这是一个有用的答案。FWIW,Kamaelia设置背后的核心原因是使并发更加安全&更易于在python系统中使用,无需摇尾乞怜。(即一大桶组件 我能理解为什么卡迈利亚的另一个答案被修改了,因为即使对我来说,它看起来更像一个广告而不是一个答案。作为《卡迈利亚》的作者,很高兴看到热情,尽管我希望其中包含一些更相关的内容:-) 这就是我的说法,请注意这个答案在定义上是有偏见的,但对我来说,Kamaelia的目的是尝试总结IMO的最佳实践。我建议尝试一些系统,看看哪个适合你。(如果这不适用于堆栈溢出,对不起-我是这个论坛的新手:-) |
6
4
一个完整的在线游戏(massivly multiplayer)是围绕Stackless及其多线程原理构建的——因为最初的游戏只是为了降低游戏的massivly multiplayer属性。 CPython中的线程被广泛禁止。一个原因是GIL(一个全局解释器锁),它为执行的许多部分序列化线程。我的经验是,以这种方式创建快速应用程序确实很困难。在我的示例编码中,所有线程的速度都比较慢——只有一个内核(但许多等待输入的操作应该可以提高性能)。
|
7
3
如果你真的想弄脏你的手,你可以试试 using generators to fake coroutines . 就所涉及的工作而言,它可能不是最有效率的,但是协同程序确实为您提供了非常好的控制 合作社 多任务处理,而不是先发制人的多任务处理。 你会发现一个优点是,总的来说,在使用协作式多任务处理时,你不需要锁或互斥,但对我来说更重要的优点是“线程”之间的切换速度几乎为零。当然,据说Stackless Python在这方面也很好;还有Erlang,如果没有的话 有 成为Python。 协作式多任务处理的最大缺点可能是通常缺乏阻止I/O的变通方法。在伪造的协作程序中,您还将遇到一个问题,即除了线程内堆栈的顶层之外,您无法从任何地方切换“线程”。 在您使用伪协程创建了一个稍微复杂的应用程序之后,您将真正开始欣赏在操作系统级别进行进程调度的工作。 |
July · 如何定义数字间隔,然后四舍五入 1 年前 |
user026 · 如何根据特定窗口的平均值(行数)创建新列? 1 年前 |
Ashok Shrestha · 需要追踪特定的颜色线并获取坐标 1 年前 |
Nicote Ool · 在FastApi和Vue3中获得422 1 年前 |
Abdulaziz · 如何对集合内的列表进行排序[重复] 1 年前 |
asmgx · 为什么合并数据帧不能按照python中的预期方式工作 1 年前 |