python协程

Python并发编程系列之常用概念剖析:并行 串行 并发 同步 异步 阻塞 非阻塞 进程 线程 协程

老子叫甜甜 提交于 2020-02-25 11:13:19
1 引言   并发、并行、串行、同步、异步、阻塞、非阻塞、进程、线程、协程是并发编程中的常见概念,相似却也有却不尽相同,令人头痛,这一篇博文中我们来区分一下这些概念。 2 并发与并行   在解释并发与并行之前,我们必须先明确: 单个处理器(一个单核CPU)在某一个时刻只能处理一个线程 。   并发是指在同一个处理器上通过时间片轮转的方式在多个线程之间频繁切换,由于切换速度极快,所以看似多个线程似乎被同时执行,但实际上每一个时刻都只有一个线程被执行,其他的线程出于阻塞状态。   并行是指多个处理器在同一时刻同时处理了多个不同的线程,这才是真正意义的同时被执行。   如下图所示,线程A与线程B同在一个CPU内执行,且任一t时刻内,都只有一个线程(A或者B)被执行,所以线程A与线程B是并发执行的。线程C和线程D分别在两个CPU内执行,且在某一个t时刻内同时都在执行,所以线程C和线程D是并行的。 3 并行与串行   上面已经说到,并行是指多个任务同时执行,而 串行 是指多个任务时,各个任务按顺序执行,完成一个之后才能进行下一个。   所以,并发与并行是在某一时刻是否都在执行的区别。并行与串行是同时进行或一个结束才进行下一个的区别。 4 同步与异步   同步与异步的概念与消息的通知机制有关:    同步 是指线程在访问某一资源时,获得了资源的返回结果之后才会执行其他操作

Python面试题之Python面试题汇总

自闭症网瘾萝莉.ら 提交于 2020-02-24 09:00:44
在这篇文章中: Python基础篇 1:为什么学习Python 2:通过什么途径学习Python 3:谈谈对Python和其他语言的区别 Python的优势: 4:简述解释型和编译型编程语言 5:Python的解释器种类以及相关特点? 6:位和字节的关系 7:b、B、KB、MB、GB的关系 8:PE8规范 9:通过代码实现如下转换(进制之间转换) 10:请编写一个函数实现将IP地址转换成一个整数 11、python递归的最大层数?998 12:求结果(and or or) 运算符 13 :ascii、unicode、utf-8、gbk 区别 14:字节码和机器码的区别 15:三元运算写法和应用场景? 16:Python3和Python2的区别? 17:用一行代码实现数值交换 18:Python3和Python2中int和long区别 19:xrange和range的区别 20:文件操作时:xreadlines和readlines的区别? 21: 列列举布尔值为False的常见值? 22. 字符串、列表、元组、字典每个常用的5个方法? 23、 lambda表达式格式以及应用场景? 24. pass的作用 25. *arg和**kwarg作用 26. is和==的区别 27:谈谈Python的深浅拷贝?以及实现方法和应用场景。 28. Python垃圾回收机制? 29.

Python语言高频重点汇总

我怕爱的太早我们不能终老 提交于 2020-02-20 17:55:37
Python语言高频重点汇总 GitHub面试宝典仓库——点这里跳转 文章目录 Python语言高频重点汇总 **GitHub面试宝典仓库——点这里跳转** 1. 函数-传参 2. 元类 3. @staticmethod和@classmethod两个装饰器 4. 类属性和实例属性 5. Python的自省 6. 列表、集合、字典推导式 7. Python中单下划线和双下划线 8. 格式化字符串中的%和format 9. 迭代器和生成器 10. args和**kwargs 11. 面向切面编程AOP和装饰器 12. 鸭子类型 13. Python中的重载 14. 新式类和旧式类 15. `__new__`和`__init__`的区别 16. Python中的作用域 17. GIL线程全局锁 18. 协程 19. 闭包 20. lambda匿名函数 21. Python中函数式编程 22. Python中的拷贝 23. Python的垃圾回收机制 24. List 25. Python中的is 26. read, readline和readlines 27. Python2和Python3的区别 28. super init 1. 函数-传参 回到顶部 在python中,给一个函数传递参数其实是把实参这个变量对应的地址复制了一份,然后把复制的这个地址传递给函数中局部变量形参

Python_面试宝典_高级

两盒软妹~` 提交于 2020-02-16 14:18:40
python中的类方法、类实例方法、静态方法有什么区别? 类方法:是类对象的方法,在定义时需要在上方使用“@classmethod”进行装饰,形参为 cls 表示类对象,类对象和实例对象都可调用。 类实例方法:是类实例化对象的方法,只有实例对象可以调用,形参为 self ,指代对象本身 静态方法:是一个任意函数,在其上方使用“@staticmethod”进行装饰,可以用对象直接调用,静态方法实际上跟该类没有太大关系。 python函数调用的时候参数的传递方式是值传递还是引用传递? python的参数传递有:位置参数、默认参数、可变参数、关键字参数 函数的传值到底是值传递还是引用传递,要分情况: 不可变参数值传递:像整数和字符串这样的不可变对象,是通过拷贝进行传递的,因为你无论如何都不可能在原处改变不可变对象。 可变参数是引用传递的: 比如像列表,字典这样的对象是通过引用传递的、和c语言里面的指针传递数组很类似,可变对象能在函数内部改变。 对缺省参数的理解? 缺省参数指在调用函数的时候没有传入参数的情况下,调用默认的参数,在调用函数的同时赋值时,所传入的参数会代替默认参数。 *args 是不定长参数,它可以表述输入参数的不确定的,可以是任意多个 **kwargs 是关键字参数,赋值的时候是以 = 值的方式,参数是可以任意多对在定义函数的时候不确定会有多少参数会传入,就可以使用两个参数

Python—迭代器和生成器

送分小仙女□ 提交于 2020-02-16 01:23:00
楔子 假如我现在有一个列表l=['a','b','c','d','e'],我想取列表中的内容,有几种方式? 首先,我可以通过索引取值l[0],其次我们是不是还可以用for循环来取值呀? 你有没有仔细思考过,用索引取值和for循环取值是有着微妙区别的。 如果用索引取值,你可以取到任意位置的值,前提是你要知道这个值在什么位置。 如果用for循环来取值,我们把每一个值都取到,不需要关心每一个值的位置,因为只能顺序的取值,并不能跳过任何一个直接去取其他位置的值。 但你有没有想过,我们为什么可以使用for循环来取值? for循环内部是怎么工作的呢? 迭代器 python中的for循环 要了解python中的for循环是怎么回事儿,咱们还是要从代码的角度出发。 首先,我们对一个列表进行for循环。 for i in [1,2,3,4]: print(i) 上面这段代码肯定是没有问题的,但是我们换一种情况,来循环一个数字1234试试 for i in 1234 print(i) 结果: Traceback (most recent call last): File "test.py", line 4, in <module> for i in 1234: TypeError: 'int' object is not iterable 看,报错了!报了什么错呢?“TypeError: 'int'

python threading实例解析diaoyo'n

隐身守侯 提交于 2020-02-15 02:54:04
1.认识GIL: 说到GIL一直是代码专家们一直以来想要解决的问题,也是被许多程序员诟病的,下面带领大家看下官方threading模块document中如何去描述对于GIL这个全局解释器锁的: https://docs.python.org/3/library/threading.html 全局解释器锁 所使用的机制 的CPython 解释器来确保只有一个线程执行的Python 字节码 在一个时间。 通过使对象模型(包括关键的内置类型,例如 dict )隐式安全地防止并发访问 ,从而简化了CPython的实现 。 锁定整个解释器可以使解释器更容易进行多线程处理,但会牺牲多处理器机器提供的许多并行性。 但是,某些扩展模块(标准的或第三方的)被设计为在执行诸如压缩或散列之类的计算密集型任务时释放GIL。 另外,在执行I / O时,始终释放GIL。 过去创建“自由线程”解释器(一种以更精细的粒度锁定共享数据的解释器)的努力并未成功,因为在常见的单处理器情况下性能会受到影响。 相信克服该性能问题将使实施更加复杂,因此维护成本更高。 在这里专门对全局解释器锁的概念引入时说了这么一段话,第一指明了GIL造成了python解释器一次只有一个线程可以获取解释器锁,也就是解释器本身是自带锁的,谁先拿到谁就可以抢占到cpu的资源, 从而导致了python无论一个线程怎么去跑

Python中使用多进程来实现并行处理的方法小结

依然范特西╮ 提交于 2020-02-14 00:02:35
Python中使用多进程来实现并行处理的方法小结 进程和线程是计算机软件领域里很重要的概念,进程和线程有区别,也有着密切的联系,先来辨析一下这两个概念: 1.定义 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源. 2.关系 一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行. 相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。 3.区别 进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。 简而言之,一个程序至少有一个进程

python之gevent模块实现协程

烂漫一生 提交于 2020-02-13 09:03:55
Python通过 yield 提供了对协程的基本支持,但是不完全。而第三方的gevent为Python提供了比较完善的协程支持。 gevent是第三方库,通过greenlet实现协程,其基本思想是: 当一个greenlet遇到IO操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。 由于切换是在IO操作时自动完成,所以gevent需要修改Python自带的一些标准库,这一过程在启动时通过monkey patch完成: from gevent import monkey; monkey.patch_socket() import gevent def f(n): for i in range(n): print gevent.getcurrent(), i g1 = gevent.spawn(f, 5) g2 = gevent.spawn(f, 5) g3 = gevent.spawn(f, 5) g1.join() g2.join() g3.join() 运行结果: <Greenlet at 0x10e49f550: f(5)> 0 <Greenlet at 0x10e49f550: f(5)>

Python协程

江枫思渺然 提交于 2020-02-13 05:32:49
一、一些基本概念: 协程(Coroutine),又称微线程,纤程,一种用户级的轻量级线程。 栈(Stack)是一个数据集合,可以理解为只能在一端进行插入或删除操作的列表。 协程拥有自己的寄存器上下文和栈,协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。因此:协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态。 在并发编程中,协程与线程类似,每个协程表示一个执行单元,有自己的本地数据,与其他协程共享全局数据和其他资源 协程需要用户自己来编写调度逻辑,对于CPU来说,协程其实是单线程,所以cpu不用去考虑怎么调度,切换上下文,这就省去了cpu的切换开销,所以协程一定程度上又好于多线程 协程存在的意义:对于多线程应用,CPU通过切片的方式来切换线程间的执行,线程切换时需要耗时(保存状态,下次继续)。协程,则只使用一个线程,在一个线程中规定某个代码块执行顺序。 协程的适用场景:当程序中存在大量不需要CPU的操作时(IO),适用于协程; 二、yield回顾: def f(): print('ok1') count=yield 5 print(count) print('ok2') yield 6 gen=f() # ret=next(gen) # print(ret) ret=gen

Python多线程

我的梦境 提交于 2020-02-11 19:31:02
多线程的使用 关于线程、进程以及协程我相信在所有的语言中都会涉及到,它们的功能非常强大,我对于这三种的学习也不够深,在今后的生活中会一直学习下去,今天我就先把我学到的记录一下,时刻勉励自己学习。 线程 多线程类似同时执行多个不同的程序,每个独立的线程都有一个程序的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。线程的概念理解起来可能比较抽象,它是操作系统能够进行运算调度的最小单位。本质上是一串指令的集合。 在python3中,我们使用threading模块来支持多线程,那么我们先来写一个最简单的多线程: import threading import time def run1(): print('我是第一个线程') time.sleep(2) def run2(): print('我是第二个线程') time.sleep(2) start_time=time.time() t1=threading.Thread(target=run1) t2=threading.Thread(target=run2) t1.start() t2.start() t1.join() t2.join() end_time=time.time() print(end_time-start_time) output: 我是第一个线程