栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

python学习笔记之--python的多线程以及并发操作

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python学习笔记之--python的多线程以及并发操作

python学习笔记之--python的多线程以及并发操作
  • 1、什么是多线程
  • 2、多线程的作用
  • 3、常见的程序运行方式
  • 4、cpu密集与io密集的区别
  • 5、了解GIL全局解释器锁
  • 6、多线程的运用
  • 7、Python中的queue队列
  • 8、生产者-消费者模式
  • 9、线程池的使用
    • 9.1、submit方法:
    • 9.2、map方法

1、什么是多线程

说起进程,就不得不说下程序。程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念。

而进程则是执行程序的一次执行过程,它是一个动态的概念。是系统资源分配的单位
通常在一个进程中可以包含若干个线程,当然一个进程中至少有一个线程,不然没有存在的意义。线程是CPU调度和执行的的单位。

注意:很多多线程是模拟出来的,真正的多线程是指有多个cpu,即多核,如服务器。如果是模拟出来的多线程,即在一个cpu的情况下,在同一个时间点,cpu只能执行一个代码,因为切换的很快,所以就有同时执行的错局。

2、多线程的作用
能大幅度提高程序的运行效率,优化用户体验,大大地缩短了程序的运行时间
3、常见的程序运行方式

4、cpu密集与io密集的区别

注意:多线程只能进行并发操作,而不能利用多cpu(存在GIL全局解释器锁),利用的也是cpu与io可以并行运行的原理

5、了解GIL全局解释器锁

全局解释器锁(英语:Global Interpreter Lock,缩写GIL)
是计算机程序设计语言解释器用于同步线程的一种机制,它使得任何时刻仅有一个线程在执行。
即便在多核心处理器上,使用GIL的解释器也只允许同一时间执行一个线程。
这也是导致python执行速度慢的一个原因

表示了同一时刻只有一个线程在执行

GIL的作用:主要是为了解决多线程之间数据完整性和状态同步问题
虽然不能利用多核cpu的优势,但是还是可以实现cpu与io并行的操作,也可以大幅提升速度

6、多线程的运用

主要用到threading的Thread类

  • target 表示方法名
  • args 表示方法所需的参数
  • Name 表示线程名字
7、Python中的queue队列

  • Queue.qsize() 返回队列的大小
  • Queue.empty() 如果队列为空,返回True,反之False
  • Queue.full() 如果队列满了,返回True,反之False
  • Queue.full 与 maxsize 大小对应
  • Queue.get([block[, timeout]])获取队列,timeout等待时间
  • Queue.get_nowait() 相当Queue.get(block=False) // block=False表示当没元素时不等待,直接抛出Empty 异常
  • Queue.put(item) 写入队列,timeout等待时间
  • Queue.put_nowait(item) 相当Queue.put(item,block=False) // block=False表示当没元素时不等待,直接抛出Full异常
  • Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号
  • Queue.join() 实际上意味着等到队列为空,再执行别的操作
8、生产者-消费者模式

实际上本质就是,定义一个中间的缓冲区作为生产者与消费者交互的通道,比如餐厅这一场景,以柜台为中间件,生产者生产好后,就调用中间件中push的方法,消费者消费完后就调用中间件的pop方法,再加一定的数量限制即可
即由中间件容器创造资源的增删改的操作
消费者就只负责消费商品,进行删的获取操作
生产者就负责生产商品,负责增加的操作

9、线程池的使用

系统启动一个新线程的成本是比较高的,因为它涉及与操作系统的交互。在这种情形下,使用线程池可以很好地提升性能,尤其是当程序中需要创建大量生存期很短暂的线程时,更应该考虑使用线程池,以此来避免过大的线程的创建与销毁的开销
线程池在系统启动时即创建大量空闲的线程,程序只要将一个函数提交给线程池,线程池就会启动一个空闲的线程来执行它。当该函数执行结束后,该线程并不会死亡,而是再次返回到线程池中变成空闲状态,等待执行下一个函数
线程的生命周期

线程池使用的是concurrent.futures 下的ThreadPoolExecutor类

  • submit(fn, *args, **kwargs):将 fn 函数提交给线程池。*args 代表传给 fn 函数的参数,*kwargs 代表以关键字参数的形式为 fn 函数传入参数。
  • map(func, *iterables, timeout=None, chunksize=1):该函数类似于全局函数 map(func, *iterables),只是该函数将会启动多个线程,以异步方式立即对 iterables 执行 map 处理。
  • shutdown(wait=True):关闭线程池。
9.1、submit方法:

submit方法将传入的方法交给线程池,后面直接跟参数值或者关键字传值,返回future对象

  • future.result() 方法获取方法的返回值
  • future.add_done_callback(function) 方法在线程任务完成时自动调用回调方法,此为非阻塞的获取线程执行的结果,直接future.result()会导致阻塞线程
  • as_completed 函数,通过这个函数遍历获取future结果的是异步获取结果,即哪个任务先完成就先输出
9.2、map方法

异步执行方法,顺序输出

注意:zip([1,2],[‘a’,’b’]) ==> [(1,’a’),(2,’b’)]

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1030057.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号