协程

gevent 协程 使用

删除回忆录丶 提交于 2020-02-13 15:31:28
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)>

Goroutine并发控制

痴心易碎 提交于 2020-02-13 12:57:07
目录 创建协程 控制Gorutine的数量 创建协程 jobCount := 10 // sync.WaitGroup 监控所有协程的状态,从而保证主协程结束时所有的子协程已经退出 group := sync.WaitGroup{} for i:=0;i < jobCount;i++ { group.Add(1) go func(i int) { fmt.Println("task ",i) time.Sleep(time.Second) // 刻意睡 1 秒钟,模拟耗时 group.Done() }(i) fmt.Printf("index: %d,goroutine Num: %d \n", i, runtime.NumGoroutine()) } group.Wait() 运行结果: index: 0,goroutine Num: 2 index: 1,goroutine Num: 3 task 0 index: 2,goroutine Num: 4 index: 3,goroutine Num: 5 task 3 task 2 index: 4,goroutine Num: 6 index: 5,goroutine Num: 7 index: 6,goroutine Num: 8 task 4 index: 7,goroutine Num: 9 task 6 index:

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)>

gevent协程

只愿长相守 提交于 2020-02-13 06:46:19
Python通过 yield 提供了对协程的基本支持,但是不完全。而第三方的gevent为Python提供了比较完善的协程支持。 gevent是第三方库,通过greenlet实现协程,其基本思想是: 当一个greenlet遇到IO操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。 由于切换是在IO操作时自动完成,所以gevent需要修改Python自带的一些标准库,这一过程在启动时通过monkey patch完成: 先了解greenlet,这个库用来学习的 功能不是很多。 1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 5 from greenlet import greenlet 6 7 8 def test1(): 9 print 12 10 #切换到g2 11 gr2.switch() 12 print 34 13 #切换到g2继续执行上次的任务 14 gr2.switch() 15 16 17 def test2(): 18 print 56 19 gr1.switch() 20 print 78 21 22 gr1 =

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

Generator

血红的双手。 提交于 2020-02-13 05:00:14
基本概念 Generator函数是ES6提供的一种异步编程解决办法,语法行为与传统函数完全不同。 Generator函数有多种理解角度。语法上,首先可以把它理解成,Generator函数是一个状态机,封装了多个内部状态。 执行Generator函数会返回一个遍历器对象,也就是说,Generator函数除了状态机,还有一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历Generator函数内部的每一个状态。 形式上,Generator函数是一个普通函数,但是有两个特征 function关键字与函数名之间有一个星号。 函数体内部使用yield表达式,定义不同的内部状态。 function* helloWorldGenerator() { yield 'hello'; yield 'world'; return 'ending'; } var hw = helloWorldGenerator(); 上面代码定义了一个Generator函数helloWorldGenerator,它内部有两个yield表达式(hello和world),即该函数有三个状态:hello,world和return语句(语句执行)。 然后,Generator函数的调用方法与普通函数一样,也是在函数名后面加上一堆圆括号。不同的是,提哦啊用Generator函数后,函数并不执行,返回的也不是函数运行结果

unity面试的基础问题(1)

浪尽此生 提交于 2020-02-12 11:44:46
oop:面对对象 特点: 继承:构造函数(先创建父类再子类)析构函数(先销毁子类然后父类) 多态:父类的指针指向子类而调用子类的方法 封装:不被别的访问 装箱:将值变为引用类型 拆箱:将引用类型变为值类型 内存分类: 栈:先进后出 参数/new 值类型/申明变量 堆:new的引用类型分配在堆上 (还有ref和out结合起来可学习一下) 全局变量:static 静态 const 常量 代码区;编译的方法(基本用不着) 下面有个需要注意的小问题Button的事件最好在堆上开辟 进程 线程 协程的区别? 1,进程拥有自己独立的堆和栈。(既不共享堆,亦不共享栈,进程由操作系统调度) 2,线程拥有自己独立的栈和共享的堆。(共享堆,不共享栈,线程亦由操作系统调度(标准线程是的))(线程是在主线程里开辟的(和主线程不是并列关系,不能在同一时间启用同一资源)) 3,协程和线程一样共享堆,不共享栈,协程由程序员在协程的代码里显示调度。(协程是在主线程里开辟的,不需要开锁) 一个应用程序一般对应一个进程,一个进程一般有一个主线程,还有若干个辅助线程,线程之间是平行运行的,在线程里面可以开启协程,让程序在特定的时间内运行。 协程和线程的区别是:协程避免了无意义的调度,由此可以提高性能,但也因此,程序员必须自己承担调度的责任,同时,协程也失去了标准线程使用多CPU的能力。 lock 一个方法锁(具体可细查

python语法基础-并发编程-协程-长期维护

。_饼干妹妹 提交于 2020-02-10 05:55:57
############### 协程 ############## # 协程 # 小知识点, # 协程和进程和线程一样都是实现并发的手段, # 开启一个线程,创建一个线程,还是需要开销, # 协程 # 协程本质上是一个线程, # 什么是协程:能够在多个任务之间切换来节省一些IO时间, # 不需要再浪费线程之间的切换了,只需要做程序之间的切换, # 程序任务之间的切换也是需要消耗时间,但是开销远远小于进程线程之间的切换, # from greenlet import greenlet # # 这个模块可以实现协程的多个任务的切换, # # 这个greenlet就是真正的协程模块, # # def eat(): # print("eat start") # g2.switch() # print("eat end") # # # def play(): # print("play start") # g1.switch() # print("play end") # # # g1 = greenlet(eat) # 注册, # g2 = greenlet(play) # g1.switch() # 切换 # g2.switch() """ eat start play start eat end play end 这就是实现了协程之间的切换 """ # 我们在工作中会使用进程,线程

python 池 协程

前提是你 提交于 2020-02-09 16:58:53
# 有多少个任务就开多少个进程或者线程# 什么是池 # 要在程序开始的时候,还没提交任务先创建几个线程或者进程 # 放在一个池子里,这就是池# 为什么要用池? # 如果先开好进程/线程,那么有任务之后就可以直接使用这个池中的数据了 # 并且开好的线程或者进程会一直存在在池中,可以被多个任务反复利用 # 这样极大的减少了开启\关闭\调度线程/进程的时间开销 # 池中的线程/进程个数控制了操作系统需要调度的任务个数,控制池中的单位 # 有利于提高操作系统的效率,减轻操作系统的负担# 发展过程# threading模块 没有提供池# multiprocessing模块 仿照threading写的 Pool# concurrent.futures模块 线程池,进程池都能够用相似的方式开启\使用# 线程池# import time# import random# from threading import current_thread# from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor# def func(a,b):# print(current_thread().ident,'start',a,b)# time.sleep(random.randint(1,4))# print(current

网络编程并发编程面试题

泄露秘密 提交于 2020-02-07 23:47:48
网络编程,并发编程 面试题1. 简述 OSI 七层协议。应用层与其它计算机进行通讯的一个应用,它是对应应用程序的通信服务的。例如,一个没有通信功能的字处理程序就不能执行通信的代码,从事字处理工作的程序员也不关心OSI的第7层。但是,如果添加了一个传输文件的选项,那么字处理器的程序员就需要实现OSI的第7层。示例:TELNET,HTTP,FTP,NFS,SMTP等。表示层这一层的主要功能是定义数据格式及加密。例如,FTP允许你选择以二进制或ASCII格式传输。如果选择二进制,那么发送方和接收方不改变文件的内容。如果选择ASCII格式,发送方将把文本从发送方的字符集转换成标准的ASCII后发送数据。在接收方将标准的ASCII转换成接收方计算机的字符集。示例:加密,ASCII等。会话层它定义了如何开始、控制和结束一个会话,包括对多个双向消息的控制和管理,以便在只完成连续消息的一部分时可以通知应用,从而使表示层看到的数据是连续的,在某些情况下,如果表示层收到了所有的数据,则用数据代表表示层。示例:RPC,SQL等。传输层这层的功能包括是否选择差错恢复协议还是无差错恢复协议,及在同一主机上对不同应用的数据流的输入进行复用,还包括对收到的顺序不对的数据包的重新排序功能。示例:TCP,UDP,SPX。网络层这层对端到端的包传输进行定义,它定义了能够标识所有结点的逻辑地址