2021/6/5 并发编程-线程2
2021/6/5 20:23:52
本文主要是介绍2021/6/5 并发编程-线程2,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
''' 同一进程下多线程共享全局变量 守护线程: 随父线程的结束而结束,无法继续创建子线程 Thread.daemon/setDaemon(True) = True 互斥锁: 对公共资源进行加锁处理,防止出现数据安全问题 threading.Lock() mutex.acquire() mutex.release() GIL全局解释器锁 对于解释器的数据安全加的一把特殊锁 1. GIL不是Python的特点而是CPython解释器的特点 2. 同一进程下的多线程只有抢到了GIL锁才能获得执行权限,如果发现访问资源未释放Lock锁,则立刻释放GIL锁 3. 对于解释型语言的通病:同进程下的多线程无法利用多核优势 多进程:适用于计算密集型,效率高于多线程 多线程:适用于IO密集型,效率高于多进程,且开销更小 死锁现象: 线程A获取到Lock锁B,继续执行需要获取到Lock锁A 线程B获取到Lock锁A,继续执行需要获取到Lock锁B 从而引发死锁现象,双方卡死 递归锁: 递归锁内部存在一个counter计数器,每当调用一次acquire,则计数器+1 每当调用一次release,则计数器-1 只有当计数器为0时,RLock锁才能被抢 threading.RLock .acquire .release Semaphore信号量,在并发编程中是代指锁的概念 Semaphore可以实现创建多个锁,每个线程都可以抢到Semaphore限定数量下的锁 Semaphore内存在一个counter计数器,当调用一次release,计数器+1 当调用一次acquire,计数器-1,当计数器为0时,无法抢锁 from threading import Semaphore s = Semaphore([value]) s.acquire() s.release() Event() 线程同步 from threading import Event event = Event() .set() True .clear() False .wait() True则激活线程,False则阻塞线程 .isSet()/is_set() 获取event状态值 线程队列queue模块 队列 = 管道加锁 Queue类:先入先出 LifoQueue:先入后出 PriorityQueue((int, obj)):优先级队列 .put(obj, block=True, timeout=None) .put_nowait() .get(block=True, timeout=None) .get_nowait() .qsize() .empty() .full() .join() .task_done() 进程池 from multiprocessing import Pool p = Pool(processes=os.cpu_count()) p.apply_async(func, args=(), kwargs={}) 异步提交,创建进程任务并执行,返回ApplyResult对象 .get([timeout]) 原地阻塞,获取进程任务的返回结果 .ready() 进程任务执行完成,返回True .successful() 进程任务正常执行完成,返回True,如果在进程任务执行完成之前调用该方法,则会报错 .wait([timeout]) 等待结果变为可用 p.apply() --> p.apply_async().get() p.close() 关闭进程池 p.join([timeout]) 原地阻塞,等待进程任务执行完毕 p.terminate() 终结进程池中所有任务的运行 进程池 from multiprocess import Pool p = Pool(processes=os.cpu_count()) p.apply_async(func, args=(), kwargs={}) 异步提交进程任务,并返回ApplyResult对象 .get([timeout]) 原地阻塞,等待进程任务的返回结果 .ready() 进程执行完毕返回True .successful() 如果进程正常执行完毕,返回True,如果该方法在进程执行完毕之前调用,则会抛出异常 .wait([timeout]) 等待结果变为可用 p.apply(func, args=(), kwargs={}) 同步提交进程任务,只有上一个进程执行完毕,才会开始下一个进程任务的执行 源码大致:p.apply_async().get() p.close() 关闭进程池 p.join([timeout]) 等待所有子进程执行完毕,必须写在close、terminate的后面 p.terminate() 终结进程池中的所有进程任务 如果使用队列,则需要导入 from multiporcessing.Manager import Queue 进程池 from concurrent.futures import ThreadPoolExecutor p = ThreadPoolExecutor(max_workers=os.cpu_count()) p.submit(func, *args, **kwargs) 异步提交进程任务,返回future对象 .cancel() 取消当前进程任务,如果正在运行,则无法取消返回Fasle,否则True .cacelled() 返回进程任务是否取消成功 .running() 任务正在执行返回True .done() 任务执行完毕或取消执行,则返回True .result([timeout]) 阻塞原地,等待任务的返回结果 .exception([timeout]) 原地阻塞,获取当前任务引发的异常,如果没有则返回None .add_done_callback(func) 回调函数,当前线程执行完毕后将future作为参数传递给回调函数 p.shutdown() 关闭进程池,并原地等待所有进程任务执行完毕(close, join) p.map(func, iterable, timeout=None, chunksize=1) from concurrent.futures import ThreadPoolExecutor p = ThreadPoolExecutor(os.cpu_count()) p.submit(func, *args, **kwargs) 返回future类 .running() .done() .cancel() 终结当前进程任务,如果任务正在运行则无法终结,返沪False,否则返回True .cancelled() 如果当前任务被成功终结,返回True,否则返回False .result([timeout]) 阻塞原地,等待获取进程任务的返回结果 .exception([timeout]) 阻塞原地,等待进程任务的异常信息,如果任务正常执行完毕,则返回None .add_done_callback(fn) 回调函数,任务执行完毕自动触发,将future作为参数传递给回调函数 p.shutdown() --> close join p.map(func, iterable, timeout=None, chunksize=1) from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor p = ThreadPoolExecutor(int=os.cpu_count()) p.submit(func) future .running .done .cancel() True False .cancelled() True, False .exception([]) .result([]) .add_done_callback(fun) p.shutdown([timeout]) p.map() 协程 核心思想:单线程下实现高并发 1. 监控IO操作 gevent spawn 2. 切换CPU资源 greenlet switch 3. 保存状态 yield from gevent import spawn from gevent import monkey;monkey.patch_all() g = spawn(func, *args) Greenlet对象.join() from greenlet import greenlet, switch g = greenlet(func) g.switch() IO模型: 多路复用IO 优势在于处理多个链接 异步IO 使用回调机制,避免等待数据和拷贝数据 阻塞IO 在IO执行的两个阶段,等待数据和拷贝数据,都会被阻塞 非阻塞IO 在拷贝数据阶段被阻塞 信号驱动IO '''
这篇关于2021/6/5 并发编程-线程2的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-07-08如何在敏捷项目中实现高效测试?
- 2024-07-08用户故事一定要有 “So that...” 吗?
- 2024-07-04TiDB 资源管控的对撞测试以及最佳实践架构
- 2024-07-03万字长文聊聊Web3的组成架构
- 2024-07-02springboot项目无法注册到nacos-icode9专业技术文章分享
- 2024-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt