Python 中的多进程与线程 每个数据科学家都需要知道

本文最初发布于 FLOYDHUB 博客,经原作者 Sumit Ghosh 授权由 InfoQ 中文站翻译并分享。导读:线程和进程都是现在计算机领域比较时髦的用语。进程 (Process) 是计算机中已运行程序的实体。进程本身不会运行,是线程的容器。程序本身只是指令的集合,进程才是程序(那些指令) 的真正运行。若干进程有可能与同一个程序相关系,且每个进程皆可以同步(循序) 或不同步(平行) 的方...
摘要由CSDN通过智能技术生成

本文最初发布于 FLOYDHUB 博客,经原作者 Sumit Ghosh 授权由 InfoQ 中文站翻译并分享。

导读:线程和进程都是现在计算机领域比较时髦的用语。进程 (Process) 是计算机中已运行程序的实体。进程本身不会运行,是线程的容器。程序本身只是指令的集合,进程才是程序(那些指令) 的真正运行。若干进程有可能与同一个程序相关系,且每个进程皆可以同步(循序) 或不同步(平行) 的方式独立运行。进程为现今分时系统的基本运作单位。线程(thread),操作系统技术中的术语,是操作系统能够进行运算调度的最小单位。它被包含在进程之中,一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。今天,我们翻译并分享 Sumit Ghosh 撰写的关于 Python 中的多进程与线程的方方面面,这些内容对于每个有志于成为数据科学家的从业者都是应知必会的内容。

每个数据科学项目迟早都会面临一个不可避免的挑战:速度。使用更大的数据集会导致处理速度变慢,因此,最终不得不考虑优化算法的运行时间。正如大多数人所知道的,并行化就是这种优化的必要步骤。Python 为并行化提供了两个内置库:multiprocessing(多进程)和 threading(线程)。在本文中,我们将探讨数据科学家如何在这两者之间进行选择,以及在选择时应记住哪些因素。

并行计算与数据科学

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

为了更好地理解并行性,让我们考虑一个真实世界的类比。假设你需要打扫家里的三个房间,你可以一个人包揽所有的事情:一个接一个地打扫房间,或者你也可以叫来两个人帮助你,你们每个人只打扫一个房间。在后一种方法中,每个人都并行地处理整个任务的一部分,从而减少完成了任务所需的总时间,这就是并行性。

在 Python 中,可以通过两种不同的方式实现并行处理:多进程和线程。

多进程和线程:理论

从根本上来说,多进程和线程是实现并行计算的两种方法,分别使用进程和线程作为处理代理。要了解这些方法的工作原理,我们就必须弄清楚什么是进程,什么是线程。

进程

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

线程

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

进程和线程(图:笔者与 Cburnett)

例如,让我们考虑一下你的计算机上正在运行的程序。你可能正在浏览器中阅读本文,浏览器可能打开了多个标签页。你还可能同时通过 Spotify 桌面应用收听音乐。浏览器和 Spotify 应用程序是不同的进程,它们中的每一个都可以使用多个进程或线程来实现并行性。浏览器中的不同标签页可能在不同的线程中运行。Spotify 可以在一个线程中播放音乐,在另一个线程中从互联网下载音乐,并使用第三个线程来显示 GUI。这就叫做多线程(multithreading)。多进程(多即个进程)也可以做到这一点。事实上,大多数像 Chrome 和 Firefox 这样的现代浏览器使用的是多进程而不是多线程来处理多个标签。

技术细节

  • 一个进程的所有线程都位于同一个内存空间中,而进程有各自独立的内存空间。
  • 与进程相比,线程更轻量级,并且开销更低。生成进程比生成线程要慢一些。
  • 在线程之间共享对象更容易,因为它们共享的是相同的内存空间。为了在进程之间实现同样的效果,我们必须使用一些类似 IPC(inter-process communication,进程间通信)模型,通常是由操作系统提供的。

并行计算的陷阱

在程序中引入并行性并不总是一个正和博弈;有一些需要注意的陷阱。最重要的陷阱如下:

  • 竞态条件: 正如我们已经讨论过的,线程具有共享的内存空间,因此它们可以访问共享变量。当多个线程试图通过同时更改同一个变量时,就会出现竞态条件。线程调度程序可以在线程之间任意切换,因此,我们无法知晓线程将试图更改数据的顺序。这可能导致两个线程中的任何一个出现不正确的行为,特别是如果线程决定基于变量的值执行某些操作时。为了防止这种情况的发生,可以在修改变量的代码段周围放置互斥锁,这样,一次只能有一个线程可以写入变量。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值