线程同步

Day40 线程同步与并发

Event事件,线程锁,线程池,全局解释器锁

08-28侠课岛    基础入门       

后端/后端/Python 由浅入深入门 12     0     253

总结

1.线程之间的几种通信方式

  • Event:事件;

  • Critical Section:临界区;

  • Semaphone:信号量;

2.Event事件

  • Event是事件处理的机制,全局定义了一个内置标志Flag,如果Flag值为 False,那么当程序执行 event.wait方法时就会阻塞,如果Flag值为True, 那么event.wait 方法时便不再阻塞;

event实例对象的对象方法:

  • wait(self, timeout=None):timeout为设置等待的时长,如果超过时长(返回值为False)则不再等待,直接向下执行,如果timeout没有指定则一 直等待,等待的时候是阻塞的没有返回值;

  • set():如果执行event.set(),将会设置flag为True,那么wait等待的线程就可以向下执行;

  • clear():如果执行event.clear(),将会设置flag标记为Flase, 那么wait等待的线程将再次等待(阻塞);

  • is_set():判断event的flag是否为True,如果为True的话wait等待的线程将向下执行;

3.线程锁

  • 锁是解决临界区资源的问题,保证每一个线程访问临界资源的时候有全部的权利;

  • 一旦某个线程获得锁, 其它试图获取锁的线程将被阻塞;

  • acquire(blocking=True,timeout=-1):加锁,默认True为加锁状态(阻塞),False为不阻塞,timeout为设置时长;

  • release():释放锁,完成任务的时候释放锁,让其他的线程获取到临界资源;

  • with lock:默认释放锁,不需要再写release()方法;

4.线程池

  • ThreadPoolExecutor构造实例的时候,传入max_workers参数来设置线程池中最多能同时运行的线程数目;

  • submit():提交线程需要执行的任务(函数名和参数)到线程池中,并返回该任务的句柄;

  • map():类似高阶函数map,可以提交任务,且传递一个可迭代对象,返回任务处理迭代对象的结果;

5.全局解释器锁

  • 尽管Python完全支持多线程编程, 但是解释器的C语言实现部分在完全并行执行时并不是线程安全的,实际上,解释器被一个全局解释器锁保护着 ,它确保任何时候都只有一个Python线程执行;

  • GIL最大的问题就是Python的多线程程序并不能利用多核CPU的优势, 就是因为GIL的存在,使得一个进程的多个线程在执行任务的时候,一个CPU时 间片内,只有一个线程能够调度到CPU上运行;

  • 因此CPU密集型的程序一般不会使用Python实现,可以选择Java,GO等语言;

  • 但是对于非CPU密集型程序,例如IO密集型程序,多数时间都是对网络IO的等待,因此Python的多线程完全可以胜任;

对于全局解释器锁的解决方案:

  • 使用multiprocessing创建进程池对象,实现多进程并发,这样就能够使用多CPU计算资源;

  • 使用C语言扩展,将计算密集型任务转移给C语言实现去处理,在C代码实现部分可以释放GIL;

多线程和多进程解决方案:

  • 如果想要同时使用多线程和多进程,最好在程序启动时,创建任何线程之前,先创建一个单例的进程池, 然后线程使用同样的进程池来进行它们的计 算密集型工作,这样类似于线程调用了进程,完成了CPU密集型任务,进程也利用了多CPU的优势;

本教程图文或视频等内容版权归侠课岛所有,任何机构、媒体、网站或个人未经本网协议授权不得转载、转贴或以其他方式复制发布或发表。

评价

12

本课评分:
  •     非常好
难易程度:
  •     适中的

内容目录



|
教程
粉丝
主页

签到有礼

已签到2天,连续签到7天即可领取7天全站VIP

  • 1
    +2 金币
  • 2
    +3 金币
  • 3
    +5 金币
  • 6
    +7 金币
  • 5
    +6 金币
  • 4
    暖心福利
    自选分类VIP ×1天
  • 7
    惊喜大礼

    自选分类VIP ×3天 +20金币
  • 持续签到 +8 金币

金币可以用来做什么?