python学习day39笔记
2021/7/23 22:29:15
本文主要是介绍python学习day39笔记,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
死锁
指两个或两个以上的进程或线程在执行过程中,因争夺资源而导致的一种互相等待的现象,若无外力作用,他们都将无法推进下去 此时称系统处于死锁状态,这些永远在互相等待的进程称为死锁进程
死锁典型问题
科学家吃面问题 一桌科学家吃面,桌上有两个叉子,吃面需要两个叉子,一个科学家抢到叉子等面,一个科学家抢到面等叉子,僵持不下,这就是死锁 from threading import Thread,Lock import time def eat1(lock1,lock2,name): lock1.acquire() print(f'{name}抢到了叉子') time.sleep(1) lock2.acquire() print(f'{name}抢到了面') time.sleep(2) print('吃饱了') lock2.release() lock1.release() def eat2(lock1,lock2,name): lock2.acquire() print(f'{name}抢到了面') time.sleep(1) lock1.acquire() print(f'{name}抢到了叉子') time.sleep(2) print('吃饱了') lock1.release() lock2.release() if __name__ == '__main__': lock1 = Lock() lock2 = Lock() for i in ['liyang','egon','jason']: t1 = Thread(target=eat1,args=(lock1,lock2,i)) t1.start() for i in ['zk','wmy','hjj']: t2 = Thread(target=eat2,args=(lock1,lock2,i)) t2.start()
解决方法
用递归锁解决死锁问题 from threading import RLock if __name__ == '__main__': lock1 = RLock() lock2 = lock1 for i in ['liyang','egon','jason']: t1 = Thread(target=eat1,args=(lock1,lock2,i)) t1.start() for i in ['zk','wmy','hjj']: t2 = Thread(target=eat2,args=(lock1,lock2,i)) t2.start() 这个RLock内部维护着一个Lock锁和一个counter变量,counter记录了acquire的次数,如果counter不为0,则其他线程无法获得锁,从而使得线程可以连续多次require
线程队列queue
queue队列:使用 import queue ,用法与进程Queue一样 在同一个进程下多个线程数据是共享的,之所以使用队列是因为队列是管道+锁,为了保证数据的安全才使用队列
先进先出
from queue import Queue if __name__ == '__main__': q = Queue() q.put('ly dsb') q.put('我最帅') print(q.get()) # ly dsb
先进后出
栈的排列方式 from queue import Queue if __name__ == '__main__': q = LifoQueue() q.put('ly dsb') q.put('我最帅') print(q.get()) # 我最帅
优先级队列
from queue import PriorityQueue if __name__ == '__main__': q = PriorityQueue() q.put((20,'ly dsb')) q.put((10,'我最帅')) # put传入一个元组,原则的第一个元素是优先级,通常是数字,也可以是非数字之间的比较,数字越小在队列内优先级越高 print(q.get()) # (10, '我最帅')
协程
协程基础
协程在线程内,线程在进程内 协程:是单线程下的并发,又称微线程,纤程。英文名Coroutine 协程是一种用户态的轻量级线程,即协程是有用户程序自己控制调度的 强调1:python的线程属于内核级别,即由操作系统控制调度(如单线程遇到io或执行时间过长就会被迫交出cpu执行权限,切换其他线程运行) 强调2:单线程内开启协程,一旦遇到io就会从应用程序级别(而非操作系统)控制切换,以此来提升效率(非io操作的切换与效率无关) 对比操作系统控制线程的切换,用户在单线程内控制协程的切换的优缺点 优点1:协程的切换开销更小,属于程序级别的切换,操作系统完全感知不到,因而更加轻量级 优点2:单线程内就可以实现并发的效果,最大限度的利用cpu 缺点1:协程的本质是单线程下,无法利用多核,可以是一个程序开启多个进程,每个进程内开启多个线程 缺点2:协程指的是单个线程,因而一旦协程出现阻塞,将会阻塞整个线程 总结协程特点: 1.必须在只有一个单线程里实现并发 2.修改共享数据不需加锁 3.用户程序里自己保存多个控制流的上下文栈 4.附加:一个协程遇到io操作自动切换到其他协程(如何实现检测io,yield、greenlet都无法实现,就用到了gevent模块(select机制))
greenlet模块
首先安装模块:pip3 install greenlet from greenlet import greenlet def num1(): print('1') g2.switch() print('2') def num2(): print('3') g1.switch() print('4') g1 = greenlet(num1) g2 = greenlet(num2) g1.switch() # 1 # 3 # 2 greenlet就是用来在线程之间来回切换运行,切换后暂停之前运行的任务
gevent模块
首先安装模块:pip install gevent import gevent def num1(): print('1') # time.sleep(2) gevent.sleep(2) print('2') def num2(): print('3') # time.sleep(2) gevent.sleep(2) print('4') g1 = gevent.spawn(num1) g2 = gevent.spawn(num2) g1.join() g2.join() # 1 # 3 # 2 # 4 gevent会自动捕捉到gevent的io操作,然后切换进程 如果非要使用time模块还要切换线程,加上猴子补丁: from gevent import monkey monkey.patch_all()
这篇关于python学习day39笔记的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-20Python编程入门指南
- 2024-12-20Python编程基础与进阶
- 2024-12-19Python基础编程教程
- 2024-12-19python 文件的后缀名是什么 怎么运行一个python文件?-icode9专业技术文章分享
- 2024-12-19使用python 把docx转为pdf文件有哪些方法?-icode9专业技术文章分享
- 2024-12-19python怎么更换换pip的源镜像?-icode9专业技术文章分享
- 2024-12-19Python资料:新手入门的全面指南
- 2024-12-19Python股票自动化交易实战入门教程
- 2024-12-19Python股票自动化交易入门教程
- 2024-12-18Python量化入门教程:轻松掌握量化交易基础知识