协程

协程

北城余情 提交于 2019-11-28 01:06:25
协程 由于GIL锁导致CPython中多线程无法并发执行,只能并发执行。而并发实现的原理就是切换+保存,那就意味着多线程实现并发,就需要为每一个任务创建一个线程。那就出现了两个问题: 问题一:必然增加了线程创建销毁与切换带来的资源开销。 问题二:高并发情况下,由于任务数量太多导致无法开启新的线程,使得即没有实际任务要执行,也无法创建新线程来处理新任务的情况。 所以应想办法避免创建线程带来的问题,同时又能保证并发效果,==协程就是使用单线程来实现多任务并发==。 协程的本质是程序员自己通过代码自己检测程序中的IO,一旦遇到IO自己通过代码切换,给操作系统的感觉是你这个线程没有任何的IO。 ps:欺骗操作系统,让它误认为你这个程序一直没有IO,从而保证了程序在运行状态和就绪态来回切换,从而提升代码的运行效率。 单线程实现并发 并发 = 切换任务+保存状态。python中的生成器就具备这样一个特定,每次调用next都会回到生成器函数中执行代码,并且是基于上一次运行的结果,这就意味着生成器会自动切换任务并保存执行状态。 # 利用生成器实现单线程的并发效果 def task1(): while True: yield print("task1 run") def task2(): g = task1() while True: next(g) print("task2 run") task2

进程_线程 之(六) --- 协程

隐身守侯 提交于 2019-11-27 22:26:45
协程简介 区别: 线程和进程的操作是由程序触发系统接口,执行者是系统;协程的操作则是程序员。 协程存在的意义: 对于多线程应用,CPU通过切片的方式来切换线程间的执行,线程切换时需要耗时(保存状态,下次继续)。协程,则只使用一个线程,在一个线程中规定某个代码块执行顺序。 协成的原理: 利用一个线程,分解一个线程成为多个微线程,注意此时从程序级别来分解的 适用场景: 当程序中存在大量不需要CPU的操作时(IO),适用于协程; 实现技术 需要手动安装 greenlet模块 和 gevent模块。 安装gevent模块会默认安装greenlet模块 基于底层greenlet实现 1 from greenlet import greenlet 2 3 def test1(): 4 print(1,2)     # 2.执行输出语句,输出1,2 5 gr2.switch()    # 3.执行完上面输出语句后,此行调用test2函数 6 print(3,4) # 6.执行输出语句,输出3,4 7 gr2.switch()    # 7.执行完上面输出语句后,此处调用test2函数 8 9 def test2(): 10 print(5,6)     # 4.执行输出语句,输出5,6 11 gr1.switch()    # 5.执行完上面输出语句后,此行调用test1函数 12 print

协程 *单线程实现并发

这一生的挚爱 提交于 2019-11-27 21:24:24
进程: 资源单位 线程: 执行单位 协程: 单线程下实现并发           并发:切换 + 保存状态           ps:看起来像同时执行的就可以称之为并发 协程:完全是程序员自己意淫出来的名词 单线程下实现并发 并发的条件?      多道技术:       空间上的复用       时间上的复用         切换 + 保存状态 实现解释:   程序员自己通过代码自己 检测程序中的IO   一旦遇到IO自己通过代码 自动切换   给操作系统的感觉是你这个线程没有任何的IO    ps:欺骗操作系统,让它误认为你这个程序一直没有IO , 从而保证程序在 运行态和就绪态来回切换,提升代码的运行效率    如何检测 IO ???     导入模块: from gevent import spawn          注意: gevent 模块没办法自动识别 time.sleep 等IO情况             需要你手动再配置一个参数  from gevent import monkey; monkey.patch_all() # 以协程实现服务端并发为例:import socket from gevent import spawn from gevent import monkey; monkey.patch_all() # # 由于该模块经常被使用

【Python协程的实现】

断了今生、忘了曾经 提交于 2019-11-27 21:09:56
原文: http://blog.gqylpy.com/gqy/233 " 补充 : 数据安全问题 进程: 多个进程操作同一个文件,会出现数据不安全线程: 多个线程操作同一个全局变量,会出现数据不安全 对于共享的数据操作: 如果是 += *= /= -= 操作,都存在数据不安全问题 如果是append,extend,pop,remove操作,就不会出现数据不安全问题协程: 永远不会出现数据不安全问题 因为协程是由程序员控制的,而程序员控制的只能是代码 协程示例代码: # 最简单的协程 a = 0 def fn1(): global a g = fn2() # 拿到生成器 next(g) # 转向fn2函数执行 a += 1 next(g) # 转向fn2函数执行 def fn2(): global a yield a += 1 yield print(fn1()) # Noneprint(a) # 2 1. 协程介绍 协程是单线程下的并发,又称微线程,纤程。英文名Coroutine。一句话说明什么是协程:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的. 1. Python的线程属于内核级别的,即由操作系统控制调度(如单线程遇到io或执行时间过长就会被迫交出cpu执行权限,切换其它线程运行) 2. 单线程内开启协程,一旦遇到io,就会从应用程序级别(而非操作系统

【Python协程的实现】

给你一囗甜甜゛ 提交于 2019-11-27 20:44:00
" 补充 : 数据安全问题 进程: 多个进程操作同一个文件,会出现数据不安全线程: 多个线程操作同一个全局变量,会出现数据不安全 对于共享的数据操作: 如果是 += *= /= -= 操作,都存在数据不安全问题 如果是append,extend,pop,remove操作,就不会出现数据不安全问题协程: 永远不会出现数据不安全问题 因为协程是由程序员控制的,而程序员控制的只能是代码 协程示例代码: # 最简单的协程 a = 0 def fn1(): global a g = fn2() # 拿到生成器 next(g) # 转向fn2函数执行 a += 1 next(g) # 转向fn2函数执行 def fn2(): global a yield a += 1 yield print(fn1()) # Noneprint(a) # 2 1. 协程介绍 协程是单线程下的并发,又称微线程,纤程。英文名Coroutine。一句话说明什么是协程:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的. 1. Python的线程属于内核级别的,即由操作系统控制调度(如单线程遇到io或执行时间过长就会被迫交出cpu执行权限,切换其它线程运行) 2. 单线程内开启协程,一旦遇到io,就会从应用程序级别(而非操作系统)控制切换,以此来提升效率(非io操作的切换反而会降低效率!)

函数进阶-生成器

拥有回忆 提交于 2019-11-27 19:47:15
一丶yield关键字 yield的英文单词意思是生产,在函数中但凡出现yield关键字,再调用函数,就不会继续执行函数体代码,而是会返回一个值。 def func(): print(1) yield print(2) yield g = func() print(g) <generator object func at 0x10ddb6b48> 生成器的本质就是迭代器,同时也并不仅仅是迭代器,不过迭代器之外的用途实在是不多,所以我们可以大声地说:生成器提供了非常方便的自定义迭代器的途径。并且从Python 2.5+开始,[PEP 342:通过增强生成器实现协同程序]的实现为生成器加入了更多的特性,这意味着生成器还可以完成更多的工作。这部分我们会在稍后的部分介绍。 def func(): print('from func 1') yield 'a' print('from func 2') yield 'b' g = func() print(F"g.__iter__ == g: {g.__iter__() == g}") res1 = g.__next__() print(f"res1: {res1}") res2 = next(g) print(f"res2: {res2}") # next(g) # StopIteration g.__iter__ == g: True

python从入门到放弃之协程

跟風遠走 提交于 2019-11-27 18:52:30
协程 协程,又称微线程,纤程。英文名Coroutine。 协程的概念很早就提出来了,但直到最近几年才在某些语言(如Lua)中得到广泛应用。 子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B,B在执行过程中又调用了C,C执行完毕返回,B执行完毕返回,最后是A执行完毕。 所以子程序调用是通过栈实现的,一个线程就是执行一个子程序。 子程序调用总是一个入口,一次返回,调用顺序是明确的。而协程的调用和子程序不同。 协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。 线程和进程的操作是由程序触发系统接口,最后的执行者是系统;协程的操作则是程序员。 协程可以被认为是一种用户空间线程,与传统的抢占式线程相比,有2个主要的优点: 与线程不同,协程是自己主动让出CPU,并交付他期望的下一个协程运行,而不是在任何时候都有可能被系统调度打断。因此协程的使用更加清晰易懂,并且多数情况下不需要锁机制。 与线程相比,协程的切换由程序控制,发生在用户空间而非内核空间,因此切换的代价非常的小。 某种意义上,协程与线程的关系类似与线程与进程的关系,多个协程会在同一个线程的上下文之中运行。 协程存在的意义:对于多线程应用,CPU通过切片的方式来切换线程间的执行,线程切换时需要耗时(保存状态,下次继续)。协程,则只使用一个线程

协程

和自甴很熟 提交于 2019-11-27 16:51:20
一、协程是什么?   协程又叫微线程,从技术的角度来说,“协程就是你可以暂停执行的函数”。如果你把它理解成“就像生成器一样”,那么你就想对了。 线程和进程的操作是由程序触发系统接口,最后的执行者是系统;协程的操作则是程序员。   协程存在的意义:对于多线程应用,CPU通过切片的方式来切换线程间的执行,线程切换时需要耗时(保存状态,下次继续)。协程,则只使用一个线程,在一个线程中规定某个代码块执行顺序。   协程的适用场景:当程序中存在大量不需要CPU的操作时(IO),适用于协程。   随着对于效率的不断提高,基于单线程来实现并发成为一个新的课题,只用一个主线程实现并发,这样就可以节省创建进程消耗的时间。   需要强调的是: #1. python的线程属于内核级别的,即由操作系统控制调度(如单线程遇到io或执行时间过长就会被迫交出cpu执行权限,切换其他线程运行) #2. 单线程内开启协程,一旦遇到io,就会从应用程序级别(而非操作系统)控制切换,以此来提升效率(!!!非io操作的切换与效率无关)   对比操作系统控制对比操作系统控制线程的切换,用户在单线程内控制协程的切换,有点如下: #1. 协程的切换开销更小,属于程序级别的切换,操作系统完全感知不到,因而更加轻量级 #2. 单线程内就可以实现并发的效果,最大限度地利用cpu   缺点如下: #1. 协程的切换开销更小

知识点 定时器的使用

强颜欢笑 提交于 2019-11-27 15:39:36
package demo_caculorimport ( "fmt" "sync" "time")func main() { //线程与协程 fmt.Println("程序开始") time.AfterFunc(3e9, func() { //此类似协程需要时间,必须注意主线程是否执行时间超过3秒 fmt.Println("程序执行") }) fmt.Println("程序结束") //通过阻塞主线程,配合协程 time.Sleep(4 * time.Second) //WaitGroup简介,等待组,实际上是一个计数器,只要计数器中有内容将一直阻塞 //WaitGroup存在于sync包中,WaitGroup只有三个方法 //Add(delta int)表示向内部计数器添加增量(delta),其中参数delta可以是负值 //Done()表示减少WaitGroup计数器的值,应该相当于在程序最后执行,相当于Add(-1) //Wait()表示阻塞直到WaitGroup计数器为0 var wg sync.WaitGroup wg.Add(5) for i := 0; i < 5; i++ { go func() { fmt.Println("执行") time.Sleep(time.Second) wg.Done() }() } wg.Wait()} 来源: https://www

【Python协程的实现】 -- 2019-08-16 22:07:16

拟墨画扇 提交于 2019-11-27 13:58:02
原文: http://blog.gqylpy.com/gqy/233 " 补充 : 数据安全问题 进程: 多个进程操作同一个文件,会出现数据不安全线程: 多个线程操作同一个全局变量,会出现数据不安全 对于共享的数据操作: 如果是 += *= /= -= 操作,都存在数据不安全问题 如果是append,extend,pop,remove操作,就不会出现数据不安全问题协程: 永远不会出现数据不安全问题 因为协程是由程序员控制的,而程序员控制的只能是代码 协程示例代码: # 最简单的协程 a = 0 def fn1(): global a g = fn2() # 拿到生成器 next(g) # 转向fn2函数执行 a += 1 next(g) # 转向fn2函数执行 def fn2(): global a yield a += 1 yield print(fn1()) # Noneprint(a) # 2 1. 协程介绍 协程是单线程下的并发,又称微线程,纤程。英文名Coroutine。一句话说明什么是协程:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的. 1. Python的线程属于内核级别的,即由操作系统控制调度(如单线程遇到io或执行时间过长就会被迫交出cpu执行权限,切换其它线程运行) 2. 单线程内开启协程,一旦遇到io,就会从应用程序级别(而非操作系统