8.7 python 日学 线程进阶、协程
1.同步
例如8.6上一篇博客最后的那个问题,之所以会出现那样的情况原因就是,没有控制多个线程对同一资源的访问,对数据造成破坏,使得线程的结果不可预期,这样的现象称为‘线程不安全’
解决思路:利用同步来进行解决
from threading import Thread,Lock
import time
g=0
def hs1():
global g
l.acquire()
for i in range(100000):
g+=1
print(‘hs1’,g)
l.release()
def hs2():
global g
l.acquire()
for i in range(100000):
g+=1
print(‘hs2’,g)
l.release()
if name == ‘main’:
l=Lock()
h1=Thread(target=hs1)
h2=Thread(target=hs2)
h1.start()
h2.start()
线程执行函数1时,对其加锁,使得函数2的请求加锁的请求被阻碍,只有函数1完全执行完毕,释放锁后,线程2才能得到锁,继续执行下去。
2.异步
同步调用就是你喊朋友去吃饭,朋友在忙,你就一直等,等你朋友忙完,你们再一起去吃饭
异步调用就是你喊朋友去吃饭,朋友在忙说忙完找你,你就去做别的事了。
from multiprocessing import Pool
import time
def zuoye(name):
print(name,‘在写代码’)
time.sleep(1)
return name+‘写完代码了’
def chouyan(status):
print(‘去抽烟因为’+status)
if name == ‘main’:
p=Pool(1)
p.apply_async(zuoye,(‘张三’,),callback=chouyan)
p.close()
p.join()
3.互斥锁
当多个线程几乎同时修改一个共享数据时,需要进行同步控制,线程同步能够保证多个线程安全的访问竞争资源,最简单的机制就是使用互斥锁
当一个线程调用锁的acquire()方法获得锁时,锁就进入locked状态,每次只有一个线程可以得到锁,,如果此时另一个线程试图获得锁,那么该线程就会变为blocked状态,直到拥有锁的线程release()
好处:
确保了某段关键代码只能由一个线程从头到尾完整的执行
坏处:
阻止了多线程的并发执行,效率下降。由于可能存在多个锁,因此可能会造成死锁。
4.死锁
如果两个线程分别占有一部分资源,并同时等待对方发资源,就会造成死锁现象。
from threading import Thread,Lock
import time
g=0
def hs1():
global g
for i in range(100000):
l1.acquire()
print(‘函数1锁1得到锁,请求锁2’)
time.sleep(1)
l2.acquire()
print(‘1111111111111111111111’)
g+=1
l2.release()
l1.release()
print(‘hs1’,g)
def hs2():
global g
for i in range(100000):
l2.acquire()
print(‘函数2锁2得到锁,请求锁1’)
time.sleep(1)
l1.acquire()
print(‘22222222222222222222222’)
l1.release()
l2.release()
g+=1
print(‘hs2’,g)
if name == ‘main’:
l1=Lock()
l2=Lock()
h1=Thread(target=hs1)
h2=Thread(target=hs2)
h1.start()
h2.start()
5.队列
import queue
q=queue.Queue(3)
q.put(1)
q.put(2)
q.put(3)
# print(‘1111111’,q.full())
# q.put(4)
while q.qsize()>0:
print(q.get())
print(‘end’)
队列优先级
import queue
q=queue.PriorityQueue(5)
q.put((1,‘a’))
q.put((5,‘xj’))
q.put((2,‘xg’))
q.put((-9,‘mg’))
while q.qsize()>0:
print(q.get())
队列后入先出
import queue
q=queue.LifoQueue(4)
q.put(1)
q.put(2)
q.put(3)
q.put(4)
while q.qsize()>0:
print(q.get())
6.threadlocal
在多线程环境下,每个线程都有自己的数据,一个线程使用自己的局部变量比使用全局变量要好,因为局部变量只有自己能看见,不会影响其他线程,而全局变量的修改必须加锁
from threading import Thread
import time,threading
local=threading.local()
def hanshu1(name):
local.name=name
# for i in range(100000):
# pass
hanshu2()
def hanshu2():
print(threading.current_thread(),local.name)
if name == ‘main’:
t1=Thread(target=hanshu1,args=(‘张三’,),name=‘线程帅哥’)
t2=Thread(target=hanshu1,args=(‘李四’,),name=‘线程美女’)
t1.start()
t2.start()
7.协程
协程是比线程更小的执行单元,协程自带上下文,只要在合适的时机,我们可以吧一个协程切换到另一个协程。通俗的理解:在一个线程中某个函数,可以在任何地方保存当前函数的一些临时变量等信息,然后在切换到另一个函数中执行,注意,这不是通过函数调用做到的,切换的次数和时机都是由开发者决定的。
这个过程看起来和线程差不多,但其实不然,线程切换从系统层面远不止保存和恢复cpu上下文那么简单,线程切换非常耗性能,但协程的切换只是单纯操作cpu上下文。
def hanshu():
a=3
for x in range(10):
yield x+a
a+=1
x=hanshu()
for y in x:
print(y)
8.7 python 日学 线程进阶、协程相关推荐
- python 进程,线程,协程篇
python 进程,线程,协程篇 ssh 线程 进程 线程,进程区别 threading 模块,两种调用方式 python GIL全局解释器锁(Global Interpreter Lock) Joi ...
- Python 进程、线程、协程
进程.线程.协程 一.线程 1. 进程和线程 线程:计算机中可以被cpu调度的最小单元(真正在工作). 进程:计算机资源分配的最小单元(进程为线程提供资源). #如容器,资源隔离使用的进程级别隔离.一 ...
- Python—进程、线程、协程
一.线程 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务 方法: ...
- Python 进程、线程、协程傻傻分不清楚?详细总结(附代码)
目录 1 什么是并发编程? 2 进程与多进程 3 线程与多线程 4 协程与多协程 5 总结 1 什么是并发编程? 并发编程是实现多任务协同处理,改善系统性能的方式.Python中实现并发编程主要依靠 ...
- Python进程、线程、协程详解
进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源的管理和分配.任务的调度. ...
- python进程、线程、协程
基本观点: 1.一个python进程一个GIL(全局锁),每个线程需要获取这个锁才能执行. 2.cpu密集型的程序,使用多进程. 3.IO密集型的程序,多线程可能会比多进程快. 4.多核cpu执行多进 ...
- python的进程线程和协程_python成长之路 :线程、进程和协程
python线程 进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源的管理和分 ...
- python 多任务、线程、协程
多任务: 初始: 多任务就是同一时刻多个任务同时执行,例如开演唱会时明星一边唱歌一边跳舞,开车时眼睛看路手操作方向盘.这些都是多任务场景. 对于电脑来说多任务就是同时运行多个应用程序,例如qq.微信. ...
- python︱Python进程、线程、协程详解、运行性能、效率(tqdm)
文章目录 多进程实践--multiprocessing . 延伸一:Caffe Python接口多进程提取特征 多线程案例--threading 1.普通的threading 4.线程锁与线程同步 5 ...
最新文章
- 第四节 RabbitMQ在C#端的应用-客户端连接
- MYSQL编译参数详解
- Oracle 常用sql整理
- ITK:将所有像素的总和缩放为常数
- QT的QOpenGLTextureBlitter类的使用
- java.net.ConnectException: Connection refused: no further information
- MFC源码解读(一)最原始一个MFC程序,手写不用向导
- AdrenoProfiler对opengles的性能分析
- mysql 存储过程 简书_MySQL学习之存储过程
- 美国“加强软件供应链安全实践的指南” (SSDF V1.1草案) 解读来了
- 闲论排样/排料算法(nesting)
- Vue3 非常好用的中文文档以及一份 Vue 3 新文档学习笔记
- 空间管理 - 碎片化问题及解决思路
- 11.23Bom完以及pc端端offset
- win8.1老是断网LOL老是掉线.net错误 问题集(win7适用)
- 在失败的滴滴出行LOGO上谈APP设计
- flash在C#中的应用
- [日推荐]『与你见字如面』信息时代的一股清流
- 2022纪中游记(进行中)
- Object IO Exercise