博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
GIL 线程池 进程池 同步 异步
阅读量:5160 次
发布时间:2019-06-13

本文共 3446 字,大约阅读时间需要 11 分钟。

1.GIL(理论 重点) 2.线程池 进程池 3.同步 异步 GIL     是一个全局解释器锁,是一个互斥锁     为了防止竞争解释器资源而产生的     为何需要gil:因为一个python.exe进程中只有一份解释器,如果这个进程开启了多个线程 都要执行代码     多线程之间要竞争解释器 一旦竞争就有可能出现问题     带来的问题:同一时间只有一个线程可以访问解释器     好处:保证了多线程的数据安全     thread-safe 线程安全的 多个线程同时访问也不会出问题     not thread-safe 非线程安全的 多个线程同时访问可能会出问题(加锁)     默认情况下一个进程只有一个线程 不会出现问题的 但是不要忘记还有GC线程     一旦出现多个线程就可能出问题 所以当初就简单粗暴的加上了GIL锁     如果你的应用程序是大量的IO操作 GIL的影响是微乎其微的     如果你的应用程序时一个大量计算操作 GIL的影响是非常大的 完全无法利用多核cpu

 

由于有GIL的存在 即使有多个cpu 也不能真正的并行 有三个任务 三个任务要并发执行 是效率最高 1.多进程 2.同一个进程下多线程 只有一个cpu     如果3个任务都要等待IO     如果是采用方案1:由于IO的时间较长 不仅不能提高效率 反而无无谓的增加了系统开销     方案2 更好 有三个cpu     如果是采用方案1 并且三个任务都没有IO操作:开启三个进程 并行的来执行 效率更高     如果是采用方案2 并且三个任务都没有IO操作:开启三个线程  必须串行执行 所以效率比进程更低 应用程序分为两种 1.IO密集型 IO操作较多 纯计算较少  采用多线程
from multiprocessing import Processfrom threading import  Thread,enumerate,current_threadimport timedef task():    with open("2.昨日回顾","rt",encoding="utf-8") as f:        f.read()if __name__ == '__main__':    start = time.time()    for i in range(100):        Thread(target=task).start()    # enumerate是所有的线程    for t in enumerate():        if t != current_thread():            t.join()    # ps = []    # for i in  range(100):    #     p = Process(target=task)    #     p.start()    #     ps.append(p)    #    # for p in ps:    #     p.join()    print(time.time()-start)
IO密集型任务
 

 

2.计算密集型 计算操作较多 IO较少  采用多进程
from multiprocessing import Processfrom threading import  Thread,enumerate,current_threadimport timedef task():    with open("2.昨日回顾","rt",encoding="utf-8") as f:        f.read()if __name__ == '__main__':    start = time.time()    for i in range(100):        Thread(target=task).start()    # enumerate是所有的线程    for t in enumerate():        if t != current_thread():            t.join()    # ps = []    # for i in  range(100):    #     p = Process(target=task)    #     p.start()    #     ps.append(p)    #    # for p in ps:    #     p.join()    print(time.time()-start)
计算密集型任务

 

应用场景:     TCP程序 应该采用多线程     纯计算 例如人脸识别 语音识别等 采取多进程 既然已经有锁了 还需要自己加锁吗? 什么情况下需要自己加锁 当多个线程需要共享一个不属于解释器资源时 必须要自己家 不加锁的例子:多个线程要并发修改某一个变量数据 from concurrent.futures import ThreadPoolExecutor 池就是容器 服务器不可能无限的开线程,所以需要对线程数量加以控制,线程池就是帮我么封装了线程数量的控制 以及线程的创建 销毁 任务的分配 使用方法一样的 线程池 在创建时 不会立即开启线程 等到提交任务时 如果没有空闲的线程 并且已存在的线程数量小于最大值 开个新的 线程开启以后就不会关闭了 直到进程全部结束为止
from concurrent.futures import ThreadPoolExecutorimport threadingdef task():    print("running............")pool = ThreadPoolExecutor(3)pool.submit(task)pool.submit(task)pool.submit(task)pool.submit(task)print(threading.active_count())print(threading.enumerate())import  timetime.sleep(3)print(threading.active_count())print(threading.enumerate())
线程池特征

 

3.同步 异步 阻塞 非阻塞     阻塞:程勋运行过程中遇到IO操作 无法继续     非阻塞:程序正在运行中,并且没有遇到IO操作 即使遇到IO也不会阻塞,cpu不会切走     指的是程序的执行状态     指的是发起人武的方式     同步:         在发起任务后必须在原地等待 任务执行完毕 才能继续往下执行     异步:         在发起任务后立即继续往下执行 不需要等待任务的执行结果     异步效率高于同步         发起异步任务的方式 就是线程和进程 同步和阻塞是完全不同的:     阻塞一定是CPU已经切走了     同步虽然也会卡住 但是CPU没切走 还在你的进程中
from concurrent.futures import  ThreadPoolExecutorpool = ThreadPoolExecutor()import timedef task(num):    time.sleep(0.5)    print("run.....")    return num ** 2ress = []for i in range(10):   res = pool.submit(task,i)    # res.result() 该函数是阻塞 会一直等到任务执行完毕 导致程序串行执行    ress.append(res)# 保证 当我要获取的时候 所有任务都已经执行完毕pool.shutdown(wait=True) # 该函数也是阻塞函数# 等到全部完成在获取结果for i in ress:    print(i.result())print("over")
同步异步

 

pool.shutdown(wait=True)该函数也是阻塞函数 关闭线程池 等到全部完成在获取结果

转载于:https://www.cnblogs.com/gengbinjia/p/10496427.html

你可能感兴趣的文章
矩阵快速幂---BestCoder Round#8 1002
查看>>
如何将应用完美迁移至Android P版本
查看>>
【转】清空mysql一个库中的所有表的数据
查看>>
基于wxPython的python代码统计工具
查看>>
淘宝JAVA中间件Diamond详解(一)---简介&快速使用
查看>>
Hadoop HBase概念学习系列之HBase里的宽表设计概念(表设计)(二十七)
查看>>
Kettle学习系列之Kettle能做什么?(三)
查看>>
Day03:Selenium,BeautifulSoup4
查看>>
awk变量
查看>>
mysql_对于DQL 的简单举例
查看>>
35. Search Insert Position(C++)
查看>>
[毕业生的商业软件开发之路]C#异常处理
查看>>
一些php文件函数
查看>>
有关快速幂取模
查看>>
Linux运维必备工具
查看>>
字符串的查找删除
查看>>
NOI2018垫底记
查看>>
快速切题 poj 1002 487-3279 按规则处理 模拟 难度:0
查看>>
Codeforces Round #277 (Div. 2)
查看>>
【更新】智能手机批量添加联系人
查看>>