浙江企业新闻网  欢迎您! 设为首页

于我而言,“水井坊”不单单指那

成都观行丨水井坊(一)香格里拉

时装周是流行的风向标,引领着穿

下一季流行穿什么?看完这次纽约

《三国志9》和《三国志11》是

TGS:我们玩了《三国志14》

大北妞我作为时尚小姐妹没事儿走

北京穿衣鄙视链:三里屯竟然不是

如何提高计算速度?应该知道这些python多线程、进程知识

2019-09-20 14:03:50 来源: 阅读:1

如何提高计算速度?应该知道这些python多线程、进程知识

正如你们大多数人已经知道的,并行化是这种优化的必要步骤。python 为并行化提供了两个内置库:多处理和线程。在这篇文章中,我们将探讨数据科学家如何在两者之间进行选择,以及在这样做时应注意哪些因素。

并行计算与数据科学

众所周知,数据科学是处理大量数据并从中提取有用见解的科学。通常情况下,我们对数据执行的操作很容易并行化,这意味着不同的处理代理可以一次对数据执行一个操作,最后进行组合以获得完整的结果。

为了更好地解释并行性,让我们拿一个真实世界的例子作为类比。假设你需要打扫你家的三个房间。你可以自己打扫,打扫完一个再打扫另一个,也可以让你的两个兄弟姐妹帮你打扫,每个人打扫一个房间。在后一种方法中,每个人完成整个任务的一部分,从而减少了完成任务所需的总时间。这就是实际中的并行性。

并行处理可以用 python 以两种不同的方式实现:多处理和线程。


多处理与线程:理论

基本上,多处理和线程是实现并行计算的两种方法,分别使用进程和线程作为处理代理。为了理解它们的工作原理,我们必须搞清楚什么是进程和线程。

如何提高计算速度?应该知道这些python多线程、进程知识

进程

进程是正在执行的计算机程序的实例。每个进程都有自己的内存空间,用来存储正在运行的指令,以及需要存储和访问才能执行的任何数据。

线程

线程是进程的组件,可以并行运行。一个进程中可以有多个线程,它们共享相同的内存空间,即父进程的内存空间。这意味着要执行的代码以及程序中声明的所有变量将由所有线程共享。

如何提高计算速度?应该知道这些python多线程、进程知识

例如,让我们回想一下正在你的计算机上运行的程序。你可能正在浏览器中阅读本文,浏览器可能打开了多个选项卡。你也可以同时通过 Spotify 桌面应用程序收听音乐。浏览器和 spotify 应用程序是不同的进程;每个进程都可以使用多个进程或线程来实现并行性。浏览器中的不同选项卡可能在不同的线程中运行。Spotify 可以在一个线程中播放音乐,在另一个线程中从 Internet 下载音乐,并使用第三个线程显示图形用户界面。这称为多线程。对多个进程进行多处理也可以做到这一点。事实上,像 chrome 和 firefox 这样的大多数现代浏览器使用多处理,而不是多线程来处理多个选项卡。

技术细节

一个进程的所有线程都存在于同一个内存空间中,而进程有各自的内存空间。

与进程相比,线程更轻量级,开销更低。生成进程比生成线程慢一点。

在线程之间共享对象更容易,因为它们共享相同的内存空间。为了实现同一个进程间通信,我们必须使用某种 IPC (inter-process communication) 模型,它通常由 OS 提供。

并行计算的陷阱

将并行性引入程序并不总是一个正和博弈,也有一些陷阱需要注意。其中,最重要的是下面的这些问题。

竞争条件:正如我们已经讨论过的,线程有一个共享内存空间,因此它们可以访问共享变量。当多个线程试图同时更改同一个变量时,会出现竞争条件。线程调度程序可以在线程之间任意交换,因此我们无法知道线程尝试更改数据的顺序。这可能会导致两个线程中的任何一个出现不正确的行为,特别是当线程决定基于变量的值执行某些操作时。为了防止这种情况发生,可以在修改变量的代码段周围放置互斥锁,以便一次只能有一个线程写入变量。

饥饿:当一个线程在较长时间内被拒绝访问某个特定的资源时,就会发生饥饿,在这种情况下,整个程序的速度会减慢。这可能是由于线程调度算法设计不当而产生的意外副作用。

死锁:过度使用互斥锁也有一个缺点——它会在程序中引入死锁。死锁是一个线程等待另一个线程释放锁时的状态,但另一个线程需要一个资源来完成第一个线程保持的操作。这样,两个线程都会停止,程序也会停止。死锁可以被认为是饥饿的极端情况。为了避免这种情况,我们必须小心不要引入太多相互依赖的锁。

活锁:活锁是指线程在循环中继续运行,但没有任何进展。这也是由于互斥锁设计不当和使用不当造成的。

如何提高计算速度?应该知道这些python多线程、进程知识

python 中的多处理和线程

全局解释器锁

说到 python,有一些奇怪的地方需要记住。我们知道线程共享相同的内存空间,因此必须采取特殊的预防措施,以便两个线程不会写入相同的内存位置。CPython 解释器使用名为 GIL 的机制或全局解释器锁来处理这个问题。


推荐阅读:叶紫