当前位置:   article > 正文

多线程和多进程的基本原理_多进程和多线程怎么实现

多进程和多线程怎么实现

前言

在一台电脑中,我们可以同时打开多个软件,例如同时看代码、听音乐、浏览网页、打字等等:

在这里插入图片描述

这是再正常不过的事情。但仔细想想,为什么计算机可以同时运行这么多软件呢?其实这就涉及到计算机中的两个名词:多进程多线程。正是多进程和多线程让我们同时可以在电脑上做很多事情,大幅提升我们的使用效率。

同样,在编写爬虫程序的时候,为了提高爬取效率,我们可能会同时运行多个爬虫任务,其中同样涉及到多进程和多线程 。今天跟大家详细聊聊多进程和多线程那些年的事儿。


一、多线程的含义

说起多线程,就不得不先说什么是线程。说起线程,又不得不先说什么是进程

在这里插入图片描述

进程可以理解为一个可以独立运行的程序单位,比如打开一个浏览器,就开启了一个浏览器进程;打开一个PyCharm,就开启了一个PyCharm进程。可以看看我们的后台进程显示:

在这里插入图片描述

在一个进程中,可以同时处理很多事情,例如在浏览器进程中,可以在多个选项卡中打开多个页面,有的页面播放音乐,有的页面看小说,有的页面播放视频:

在这里插入图片描述

这些任务可以同时运行,互不干扰。为什么能做到同时运行这么多任务呢?这便引出了线程的概念,其实一个任务就对应一个线程。

进程就是线程的集合,进程是由一个或多个线程构成的,线程是操作系统进行运算调度的最小单位,是进程中的最小运行单元。以上面说的浏览器进程为例,其中的播放音乐就是一个线程,播放视频也是一个线程。当然,浏览器进程中还有很多其他线程在同时运行。

了解了线程的概念,多线程就很容易理解了。多线程就是一个进程中同时执行多个线程,上面的浏览器进程就是典型的多线程。

二、并发和并行

说到多进程和多线程,不得不再介绍两个名词——并发并行。我们知道,在计算机中运行一个程序,底层是通过处理器运行一条条指令来实现的。

并发concurrency)是指多个线程对应的多条指令被快速轮换地执行。例如一个处理器,它先执行线程A的指令一段时间,再执行线程B的指令一段时间,然后再切回线程A执行一段时间。处理器执行指令的速度和切换线程的速度都非常快,人完全感知不到计算机在这个过程中还切换了多个线程,这使得多个线程从宏观上看起来是同时在运行。从微观上看,处理器连续不断地在多个线程之间切换和执行,每个线程的执行都一定会占用这个处理器一段时间,因此同一时刻其实只有一个线程被执行。

并行parallel)指同一时刻有多条指令在多个处理器上同时执行,这意味着并行必须依赖多个处理器。不论是从宏观还是微观上看,多个线程都是在同一时刻一起执行的。

关于并行和并发,给大家举个通俗的栗子:看电视的时候,有电话进来了,我把电视暂停了,去接电话,接完了过来继续打开电视看,这叫并发,同一时间点只能干一件事。看电视的时候,有电话进来了,我看电视,让弟弟接电话,两件事情都在进行。这叫并行,同一时间点干多件事。

在这里插入图片描述

并行只能存在于多处理器系统中,因此如果计算机处理器只有一个核,就不可能实现并行。而并发在单处理器和多处理器系统中都可以存在,因为仅靠一个核,就可以实现并发。

有小伙伴可能会问了,那如何查看我的电脑是几个核呢?

首先同时按下Ctrl+Shift+Esc键,打开任务管理器,如下图:

在这里插入图片描述

然后在任务管理器里面点击性能按钮,就可以看到自己电脑是几核了,如下图我的电脑是6核:

在这里插入图片描述

假如我们电脑处理器需要同时运行多个线程,但是处理器只有一个核,那它只能通过并发的方式来运行这些线程。而如果电脑有多个核,那么在一个核执行一个线程的同时,另一个核可以执行另一个线程,这样这两个线程就实现了并行执行。当然,其他线程也可能和另外的线程在同一核上执行,它们之间就是并发执行。具体的执行方式,取决于操作系统如何调度。

三、多线程适用场景

在一个程序的进程中,有一些操作是比较耗时或者需要等待的,例如等待数据库查询结果的返回、等待网页的响应。这时如果使用单线程,处理器必须等这些操作完成之后才能继续执行其他操作,但在这个等待的过程中,处理器明显可以去执行其他操作。如果使用多线程,处理器就可以在某个线程处于等待状态的时候,去执行其他线程,从而提高整体的执行效率。

很多情况和上述场景一样线程在执行过程中需要等待。网络爬虫就是一个非常典型的例子,爬虫在向服务器发起请求之后,有一段时间必须等待服务器返回响应,这种任务就属于IO密集型任务(输入输出频繁的任务,比如文件读写,网络请求等等)。对于这种任务,如果我们启用多线程,那么处理器就可以在某个线程等待的时候去处理其他线程,从而提高整体的爬取效率。

但并不是所有任务都属于IO密集型任务,还有一种任务叫做计算密集型任务 ,也可以称为CPU密集型任务 。顾名思义,就是任务的运行一直需要处理器的参与(比如复杂的加减乘除,数据的海量处理)。这样反倒不适合多线程,因为多线程的本质就是把处理器的空闲等待时间利用起来,而计算密集型任务的处理器一直都没闲着。并且多线程的操作,线程需要频繁切换,切换的过程反而浪费更多时间,使得整体效率变低。

综上所述,如果任务不是计算密集型任务,就可以使用多线程来提高程序整体的执行效率。尤其对于网络爬虫这种IO密集型任务,使用多线程能够大大提高程序整体的爬取效率。

四、多进程的含义

前文我们已经了解了进程的基本概念,进程process)是具有“ 一定独立功能 ”的程序(比如微信、淘宝)在操作系统的一次运行活动,是系统进行资源分配和调度的一个独立单位。

顾名思义,多进程就是同时运行多个进程。由于进程就是线程的集合,而且进程是由一或多个线程构成的,所以多进程意味着有大于或者等于进程数量的线程在同时运行。

五、Python中的多线程和多进程

Python中GIL的限制导致不论是在单核还是多核条件下,同一时刻都只能运行一个线程,这使得Python多线程无法发挥多核并行的优势。

GIL全称为Global Interpreter Lock,意思是全局解释器锁,其设计之初是出于对数据安全的考虑。

在Python多线程下,每个线程的执行方式分如下三步。

  • 获取GIL。
  • 执行对应线程的代码。
  • 释放GIL。

由此可见,某个线程要想执行,必须先拿到GIL。我们可以把GIL看做通行证,并且在一个Python进程中,GIL只有一个。线程要是拿不到通行证,就不允许执行。这样会导致即使在多核条件下,一个Python进程中的多个线程也只能执行一个。

而对于多进程来说,每个进程都有属于自己的GIL,所以在多核处理器下,多进程的运行是不会受到GIL影响的。也就是说,多进程能够更好地发挥多核优势。

不过对于爬虫这种IO密集型任务来说,多线程和多进程产生的影响差别不大。但对于计算密集型任务来说,由于GIL的存在,Python多线程的整体运行效率在多核的情况下可能反而比单核更低。而Python的多进程相比多线程,运行效率在多核情况下比单核会有成倍提升。从整体来看,Python的多进程比多线程更有优势。所以如果条件允许的话,尽量用多进程。

注意:由于进程是系统进行资源分配和调度的一个独立单位,所以各进程之间的数据是无法共享的,进程之间的数据共享需要由单独的机制来实现。


总结

以上给大家介绍了多线程、多进程的基本知识,如果我们可以把多线程、多进程运用到爬虫中的话,爬虫的爬取效率将会大幅提升。关于Python爬虫中多线程和多进程的具体用法,在以后的博客会给大家介绍到。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/151391
推荐阅读
相关标签
  

闽ICP备14008679号