广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Python进阶之多线程怎么实现
  • 716
分享到

Python进阶之多线程怎么实现

2023-07-06 03:07:49 716人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

这篇文章主要介绍“python进阶之多线程怎么实现”,在日常操作中,相信很多人在Python进阶之多线程怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python进阶之多线程怎么实现”的疑惑有所帮助!

这篇文章主要介绍“python进阶之多线程怎么实现”,在日常操作中,相信很多人在Python进阶之多线程怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python进阶之多线程怎么实现”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

    线程

    想要理解线程的含义,首先我们先看一下百度百科的定义:

    线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

    简单来讲,当你打开电脑中的一个应用程序,其实此时计算机就为你创建了一个进程,系统会为其进行资源分配并且对其进行调度。而线程就是比进程还要小的单位,多个线程完成不同的工作组成了我们宏观上能够得到响应的工作结果。

    举个例子,进程就像一个大的工厂,工厂中有很多机床设备和场地。而不同的线程就像工厂中工作的工人,工厂为其分配不同的工作来完成一个最终的生产目标。我们可以指派不同的工人做不同的工作或增加工人提高我们的生产效率。

    编程中,线程可以由我们启用帮助我们完成不同的工作实现多线程并发,提高我们的代码效率。

    Python中的多线程

    在python中主要有两种实现多线程的方式:

    • 通过threading.Thread () 方法创建线程

    • 通过继承 threading.Thread 类的继承重写run方法

    接下来我们分别说一下多线程的两种实现形式。

    threading.Thread () 创建线程

    为了更直观的理解这个过程,首先我们先编写一个正常的函数,完成倒数5个数的功能,其中间隔一秒钟。

    def fuc():    for i in range(5):        time.sleep(1)

    在主函数中,我们调用Thread()来实例化两个线程,让他们同时运行。

    if __name__ == '__main__':    t1 = threading.Thread(target=fuc, args=(1,), daemon=True)    t2 = threading.Thread(target=fuc, args=(2,), daemon=True)    t2.start()    t1.start()

    整体代码如下所示:

    import threadingimport timedef fuc():    for i in range(5):        time.sleep(1)if __name__ == '__main__':    t1 = threading.Thread(target=fuc)    t2 = threading.Thread(target=fuc)    t2.start()    t1.start()

    我们先不讨论调用的函数以及传入的参数,先来看一下运行效果:

    0
    0
    11
    22
    33
    44

    可以看到,两个打印的结果基本上是同时出现的,并且出现了混合的情况,证明两个打印的函数正在同时进行。

    接下来我们就来介绍一下类的初始化参数以及我们调用的函数:

    thread.Thread(group=Nore,targt=None,args=(),kwargs={},*,daemon=None)

    在该类中主要由以下几个参数组成:

    • group:与ThreadGroup类相关,一般不使用。

    • target:线程调用的对象,就是目标函数,在上述的例子中我们传入的是我们编写的函数fuc。

    • name:线程的名字,默认是Tread-x。

    • args:为目标函数传递关键字参数,字典。

    • daemon:用来设置线程是否随主线程退出而退出,涉及到主线程相关知识,我们稍后介绍。

    接下来介绍我们常用的几个方法:

    • run():表示线程启动的活动,在第二种继承写法中会用到。

    • start():激活线程,使其能够被调度。

    • join():等待至线程终止,这个方法涉及到主线程的知识,我们稍后介绍。

    • isAlive():返回线程是否活动。

    • getName():返回线程名称。

    • setName() : 设置线程名称。

    接下来,我们使用上述参数更改示例,让函数获取一个参数,并为不同的线程设置名字。代码如下:

    import threadingimport timedef fuc(num):    for i in range(5):        print('接收到参数{}:'.fORMat(num), i)        time.sleep(1)if __name__ == '__main__':# 传入参数及名字    t1 = threading.Thread(target=fuc, args=(1,), name='t1')    t2 = threading.Thread(target=fuc, args=(2,), name='t2')    t1.start()    print(t1.getName(), '开始运行...')    t2.start()    print(t2.getName(), '开始运行...')

    运行结果如下:

    接收到参数1:t1 开始运行... 
    0
    接收到参数2: t20 开始运行...

    接收到参数1:接收到参数2: 1 
    1
    接收到参数1:接收到参数2:  2
    2
    接收到参数1:接收到参数2:  33

    接收到参数1:接收到参数2:  4
    4

    可以看到,虽然结果很混乱,但是我们传入的参数以及获取的名字都被打印出来了。

    另外,这里有两个注意:

    • trgat参数接受的是函数名字不需要加括号。

    • args传入的执行函数参数要加括号和逗号,保证其是一个元组。

    继承 threading.Thread 类的线程创建

    在上面的例子中,我们已经理解了多线程的一种创建方法。接下来我们来介绍第二种方法,这也是众多大佬很喜欢的一种方法,通过继承 threading.Thread 类的线程创建。

    class MyThread(threading.Thread):    def run(self) -> None:        for i in range(5):            print(i)            time.sleep(1)if __name__ == '__main__':    t1 = MyThread(name='t1')    t2 = MyThread(name='t2')    t1.start()    t2.start()

    运行结果如下:

    0
    0
    11
    22
    33
    44

    注意:这里调用的是start方法而不是run方法,否则会编程单线程执行。

    主线程

    在了解了多线程的编程方法之后,我们来介绍一下主线程及相关参数和方法。

    在我们执行多线程程序的过程中,存在一个主线程,而我们开辟的其他线程其实都是它的子线程。由主线程主导的工作有以下两种情况:

    • 由于主线程结束了,强制停止其它线程的工作,但此时其他线程有可能还没有结束自己的工作。

    • 主线程结束后,等待其他线程结束工作,再停止所有线程的工作。

    可以简单地理解为包工头,它是这些线程的头子!其从微观角度上讲掌管了一定的工作流程,它可以选择是否等待其它工人结束工作再结束整个工作。

    而我们可以使用参数或者方法控制这个过程。

    使用daemon参数控制过程

    在上边的函数参数介绍中,提到了daemon参数,其为False时,线程不会随主线程结束而退出,主线程会等待其结束后再退出。而为True时则不论子线程是否完成了相关工作都会直接退出。

    接下来我们看两个示例,我们修改刚才的示例代码的daemon参数为True,表示不论子线程是否完成了工作都强制退出。

    import threadingimport timedef fuc(num):    for i in range(5):        print('接收到参数{}:'.format(num), i)        time.sleep(1)if __name__ == '__main__':    t1 = threading.Thread(target=fuc, args=(1,), name='t1', daemon=True)    t2 = threading.Thread(target=fuc, args=(2,), name='t2', daemon=True)    t1.start()    print(t1.getName(), '开始运行...')    t2.start()    print(t2.getName(), '开始运行...')    print("我是主线程,都给我停下!")

    结果如下:

    接收到参数1:t1 0 
    开始运行...
    接收到参数2:t2  0
    开始运行...
    我是主线程,都给我停下!

    可以看到,子线程的倒数还没有结束,由于主线程结束了,所有线程一起结束了。 这里要注意以下几点:

    • daemon属性必须在start( )之前设置。

    • 从主线程创建的所有线程不设置daemon属性,则默认都是daemon=False。

    使用.join()阻塞线程

    除此之外,我们还可以调用.join()方法阻塞线程,调用该方法的时候,该方法的调用者线程结束后程序才会终止。

    #timeout参数表明等待的时长,不设置该参数则默认为一直等待。join(timeout-=None)

    我们来看下面这个示例,我们更改了两个函数的倒计时时间,使第一个线程的倒计时时间更长,并对第二个线程进行了阻塞操作。代码如下:

    import threadingimport timedef fuc1():    for i in range(10):        print(i)        time.sleep(1)def fuc2():    for i in range(5):        print(i)        time.sleep(1)if __name__ == '__main__':    t1 = threading.Thread(target=fuc1, name='t1', daemon=True)    t2 = threading.Thread(target=fuc2, name='t2', daemon=True)    t1.start()    print(t1.getName(), '开始运行...')    print('我是二儿子,等等我!')    t2.start()    print(t2.getName(), '开始运行...')    t2.join()    print("我是主线程,都给我停下!")

    结果如下:

    0t1
    开始运行...
    我是二儿子,等等我!
    0t2 
    开始运行...
    11
    22
    33
    44

    我是主线程,都给我停下!5

    我们可以看到,上述代码中线程一还没有结束倒数十个数,程序就结束了。在此过程中,主线程只等待了第二个线程结束,整个程序就结束了。

    线程同步

    在多个线程同步运行的情况下,会出现多个线程同时操作一个数据的情况。如果两个线程同时操作同一个变量的话,很容易出现混乱的情况。所以,我们需要一个工具来确保在同一时间只能有一个线程处理数据。

    线程类提供了来解决问题,当线程申请处理某个数据时申请一个锁来控制住当前数据,结束处理时即将锁释放。

    threading中的锁

    python的threading中为我们提供了RLock锁来解决多线程同时处理一个数据的问题。在某个时刻,我们可以让线程申请锁来保护数据此时只能供该线程使用。

    为了更好的理解该过程,我们定义一个全局变量,让每一个线程都对其操作但不设置锁,观察变量的变化:

    R_LOCK = threading.Lock()COUNT = 100class MyThread(threading.Thread):    def run(self) -> None:        global COUNT        #R_LOCK.acquire()        COUNT -= 10        time.sleep(1)        print(self.getName(), COUNT)        #R_LOCK.release()if __name__ == '__main__':    threads = [MyThread() for i in range(10)]    for t in threads:        t.start()

    结果如下:

    Thread-3Thread-10  0Thread-8Thread-7 0Thread-6 0Thread-5Thread-9
    Thread-1 0Thread-2 00  0
    Thread-4 000

    可以看到,我们的数据发生了异常,这并不是我们想要得到的结果,若把锁给关闭注释让其正常运行可以看到以下的正常结果:

    Thread-1 90
    Thread-2 80
    Thread-3 70
    Thread-4 60
    Thread-5 50
    Thread-6 40
    Thread-7 30
    Thread-8 20
    Thread-9 10
    Thread-10 0

    到此,关于“Python进阶之多线程怎么实现”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

    --结束END--

    本文标题: Python进阶之多线程怎么实现

    本文链接: https://www.lsjlt.com/news/357626.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • Python进阶之多线程怎么实现
      这篇文章主要介绍“Python进阶之多线程怎么实现”,在日常操作中,相信很多人在Python进阶之多线程怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python进阶之多线程怎么实现”的疑惑有所帮助!...
      99+
      2023-07-06
    • Python进阶之多线程的实现方法总结
      目录线程Python中的多线程threading.Thread () 创建线程继承 threading.Thread 类的线程创建主线程使用daemon参数控制过程使用.join()...
      99+
      2023-05-16
      Python多线程实现方法 Python多线程实现 Python多线程
    • Java之多线程进阶
      目录 一.上节内容复习 1.线程池的实现 2.自定义一个线程池,构造方法的参数及含义 3.线程池的工作原理 4.拒绝策略 5.为什么不推荐系统提供的线程池 二.常见的锁策略 1.乐观锁和悲观锁 2.轻量级锁和重量级锁 3.读写锁和普通互斥...
      99+
      2023-08-31
      java jvm 开发语言 javaee 多线程
    • Python进阶篇之多线程爬取网页
      目录一、前情提要二、并发的概念三、并发与多线程四、线程池一、前情提要 相信来看这篇深造爬虫文章的同学,大部分已经对爬虫有不错的了解了,也在之前已经写过不少爬虫了,但我猜爬取的数据量都...
      99+
      2022-11-12
    • Java进阶必备之多线程编程
      目录一、图示二、多线程编程三、线程的工作过程四、创建多线程一、图示 二、多线程编程 何为多线程,通俗的讲就是让你的代码同时干好几件事。 而我们的一个代码文件或者一个项目就是一个进程...
      99+
      2022-11-12
    • python之多线程与多进程
      1. 多进程与多线程 (1)背景:为何需要多进程或者多线程:在同一时间里,同一个计算机系统中如果允许两个或者两个以上的进程处于运行状态,这便是多任务。多任务会带来的好处例如用户边听歌、边上网、边打印,而这些任务之间丝毫不会互相干扰。使用多...
      99+
      2023-01-31
      之多 线程 进程
    • python怎么实现多线程
      这篇文章将为大家详细讲解有关python怎么实现多线程,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Python的优点有哪些1、简单易用,与C/C++、Java、C# 等传统语言相比,Python对代码格...
      99+
      2023-06-14
    • Python进阶多线程爬取网页项目实战
      目录一、网页分析二、代码实现上一篇文章介绍了并发和多线程的概念,这次就来向大家上一个实战来讲解一下如何真正的运用上多线程这个概念。 有需要的可以看看我之前这篇文章:Python进阶篇...
      99+
      2022-11-12
    • python多线程及多线程有序性怎么实现
      这篇文章主要介绍了python多线程及多线程有序性怎么实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇python多线程及多线程有序性怎么实现文章都会有所收获,下面我们一起来看看吧。前言多线程一般用于同时调用...
      99+
      2023-07-02
    • Node.js 中怎么实现多线程和多进程
      这期内容当中小编将会给大家带来有关Node.js 中怎么实现多线程和多进程,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。为什么要用 NodeJSJavaScript 最初...
      99+
      2022-10-19
    • Python中的多线程怎么实现
      本文小编为大家详细介绍“Python中的多线程怎么实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“Python中的多线程怎么实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。前言:多线程简单理解就是:一个CP...
      99+
      2023-07-02
    • 爬虫学习之第四章爬虫进阶之多线程爬虫
      有些时候,比如下载图片,因为下载图片是一个耗时的操作。如果采用之前那种同步的方式下载。那效率肯会特别慢。这时候我们就可以考虑使用多线程的方式来下载图片。 多线程介绍: 多线程是为了同步完成多项任务,通过提高资源使用效率来提高系统的效率...
      99+
      2023-01-31
      爬虫 进阶 第四章
    • Python怎么实现selenium多线程爬虫
      要在Python中实现Selenium多线程爬虫,你可以按照以下步骤进行操作: 导入必要的库: from selenium im...
      99+
      2023-10-24
      Python selenium
    • python thread模块怎么实现多线程
      这篇文章主要介绍“python thread模块怎么实现多线程”,在日常操作中,相信很多人在python thread模块怎么实现多线程问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”python thread...
      99+
      2023-06-30
    • Python中怎样实现多线程
      今天就跟大家聊聊有关Python中怎样实现多线程,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。线程简介多线程能让你像运行一个独立的程序一样运行一段长代码。这有点像调用子进程(subp...
      99+
      2023-06-16
    • Python多线程、异步+多进程爬虫实现代码
      安装Tornado 省事点可以直接用grequests库,下面用的是tornado的异步client。 异步用到了tornado,根据官方文档的例子修改得到一个简单的异步爬虫类。可以参考下最新的文档学习下。...
      99+
      2022-06-04
      爬虫 多线程 进程
    • java两阶段终止线程怎么实现
      这篇文章主要讲解了“java两阶段终止线程怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“java两阶段终止线程怎么实现”吧!一、怎么优雅地关闭一个线程?在一个线程T1中如何优雅地关闭...
      99+
      2023-06-25
    • python多线程数据交互怎么实现
      在Python中,可以使用多线程模块threading来实现多线程数据交互。以下是一个简单的示例: import threading...
      99+
      2023-10-22
      python
    • python多线程数据共享怎么实现
      在Python中,可以使用`threading`模块来实现多线程数据共享。具体步骤如下: 导入`threading`模块:`im...
      99+
      2023-10-26
      python
    • python多线程共享变量怎么实现
      在Python中,可以使用`threading`模块来实现多线程共享变量。 下面是一个简单的例子,展示了如何使用多线程共享变量: i...
      99+
      2023-10-27
      python
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作