协程

Python全栈(四)高级编程技巧之10.Python多任务-协程

社会主义新天地 提交于 2020-02-07 22:00:53
文章目录 一、生成器-send方法 1.同步、异步 2.堵塞、非堵塞 3.生成器的send()方法 二、使用yield完成多任务和yield from 1.使用yield完成多任务 2.yield from的使用 三、协程-使用greenlet&gevent完成多任务 1.协程概念 2.使用greenlet完成多任务 3.使用gevent完成多任务 4.gevent简单应用 5.进程、线程和协程对比 一、生成器-send方法 1.同步、异步 同步: 是指代码调用 IO操作 时,必须等待IO操作完成才返回的调用方式。 异步: 是指代码调用 IO操作 时,不必等IO操作完成就返回的调用方式。 同步异步比较如下: 2.堵塞、非堵塞 阻塞: 从调用者的角度出发,如果在调用的时候,被卡住,不能再继续向下运行,需要等待,就说是阻塞。 堵塞的例子有: 多个用户同时操作数据库和锁机制 Socket的 accept() 方法 input() 非阻塞: 从调用者的角度出发,如果在调用的时候,没有被卡住,能够继续向下运行,无需等待,就说是非阻塞。 3.生成器的send()方法 之前讲到生成器: def create_fib ( num ) : a , b = 0 , 1 current_num = 0 while current_num < num : yield a a , b = b , a + b

探讨进程、线程、协程的区别

坚强是说给别人听的谎言 提交于 2020-02-07 07:02:54
它们都是因程序的 并发 执行程序而产生 一、进程 ①、进程是资源分配的基本单位,程序运行时系统就会创建一个进程,例如打开qq应用就创建一个进程。 ②、操作系统会为它分配专门的进程控制块 ③、三种状态:就绪状态、执行状态、阻塞状态 二、线程 ①、线程是程序执行时的最小单位,一个进程可以由很多个线程组成,但至少包含一个主线程,例如qq里有多个功能则多个线程 三、协程 ①、协程是一种用户态的轻量级线程 , 它是线程更小的执行单元,它的调度完全由用户控制 四、进程与线程的区别 ①、进程开销更大:进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多。 ②、进程共享数据更复杂:同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式进行 ③、进程健壮性更好:多线程程序只要有一个线程死掉,整个进程也死掉,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间,线程之间没有单独的地址空间。 来源: https://www.cnblogs.com/legendheng/p/10068448.html

Python中多进程、多线程、协程区别和应用场景

﹥>﹥吖頭↗ 提交于 2020-02-07 04:42:10
面试很容易问到,千万别混淆: 多进程适合在CPU 密集型操作(cpu 操作指令比较多,如科学计算,位数多的浮点运算) 多线程适合在IO 密集型操作(读写数据操作较多的,比如爬虫) 线程是并发,进程是并行;进程之间相互独立,是系统分配资源的最小单位,同一个进程中的所有线程共享资源。 进程:一个运行的程序或代码就是一个进程,一个没有运行的代码叫程序。进程是系统进行资源分配的最小单位,进程拥有自己的内存空间,所以进程间数据不共享,开销大。 线程:调度执行的最小单位,也叫执行路径,不能独立存在,依赖进程的存在而存在,一个进程至少有一个线程,叫主线程,多个线程共享内存(数据共享和全局变量),因此提升程序的运行效率。 协程:用户态的轻量级线程,调度有用户控制,拥有自己的寄存器上下文和栈,切换基本没有内核切换的开销,切换灵活。 来源: https://www.cnblogs.com/kaiping23/p/9618598.html

MonoBehaviour生命周期

[亡魂溺海] 提交于 2020-02-07 01:10:58
MonoBehaviour生命周期 上图中重要的信息点很多,需要特别注意的是所有脚本的Awake方法都执行完才会执行Start,但是如果在Awake 中开启了一个协程这个协程中每一帧执行一些操作然后等待,那么Start方法执行是不会等待这个协程结束的,也就是说Start方法中的代码会比协程的代码结束早晚是不一定的。另外可以看到Unity中所有的方法都是在一个大循环里,所以协程只是换一个地方循环中的位置执行,并不是另一个线程。 在Unity脚本中,有一些按照预定顺序执行的事件函数,脚本即是按照此顺序执行的。这个执行顺序描述如下: First Scene Load 第一个场景加载 These functions get called when a scene starts (once for each object in the scene). 这些函数在场景开始时就被调用了(对场景中的每个对象执行一次)。 Awake: This function is always called before any Start functions and also just after a prefab is instantiated. Awake:这个函数是在Start函数之前以及预制物体实例化后被调用。 OnEnable: (only called if the Object is

Go 系列教程 —— 23. 缓冲信道和工作池

自闭症网瘾萝莉.ら 提交于 2020-02-06 15:59:14
什么是缓冲信道? 在上一教程里,我们讨论的主要是无缓冲信道。我们在信道的教程里详细讨论了,无缓冲信道的发送和接收过程是阻塞的。 我们还可以创建一个有缓冲(Buffer)的信道。只在缓冲已满的情况,才会阻塞向缓冲信道(Buffered Channel)发送数据。同样,只有在缓冲为空的时候,才会阻塞从缓冲信道接收数据。 通过向 make 函数再传递一个表示容量的参数(指定缓冲的大小),可以创建缓冲信道。 ch := make(chan type, capacity) 要让一个信道有缓冲,上面语法中的 capacity 应该大于 0。无缓冲信道的容量默认为 0,因此我们在上一教程创建信道时,省略了容量参数。 我们开始编写代码,创建一个缓冲信道。 示例一 package main import ( "fmt" ) func (main() { ch := make(chan string, 2) ch <- "naveen" ch <- "paul" fmt.Println(<- ch) fmt.Println(<- ch) } 在线运行程序 在上面程序里的第 9 行,我们创建了一个缓冲信道,其容量为 2。由于该信道的容量为 2,因此可向它写入两个字符串,而且不会发生阻塞。在第 10 行和第 11 行,我们向信道写入两个字符串,该信道并没有发生阻塞。我们又在第 12 行和第 13

python高级爬虫笔记(2)

坚强是说给别人听的谎言 提交于 2020-02-05 21:09:16
提高爬虫效率主要从三个方面开始复习。 并发 ip cookies 并发必然引发的一个结果就是反爬虫机制,这种时候爬虫的效率不会因为并发而提高,反而会因为网站的防御机制拖累爬虫的速度。 自然而然地就引出了2,代理爬虫。代理爬虫能够从多个ip发送请求,减小了单个ip的请求频率,自然触发反爬虫机制的概率也就小了很多。 但是新的问题又出现了,对于需要 登录 的网站,需要提交cookies来模拟登录情况,模拟登录不难,但是同一个cookies从不同的ip同时发送请求很明显不合常理,依然会触发反爬虫机制。 这是到目前为止我所遇到的影响爬虫效率的问题,就在这里做一个总结吧,如果后续遇到新的效率相关的问题,再做补充。 并发 前言 在2019年,我阅读了python cookbook,其中对这一方面有较为详细且透彻的讲述,比较适合有python基础的人学习。 多进程、多线程是python程序员的必修课之一。因为,即使脱离了爬虫,机器学习、web开发等方面,多线程、多进程依旧有着举足轻重的地位。 这是开发者的一个小分水岭,它在一定程度上决定了程序效率的高低。 python中的多进程方法 多线程、多进程、协程爬虫 对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程

20170220-coroutine

♀尐吖头ヾ 提交于 2020-02-05 09:23:39
协程 coroutine 最近频繁的听说到 “协程” 这个词,花了一段时间肤浅的研究了一下。对于 “它是一个什么东西” 有了一个大概的了解。 from wiki Coroutines are computer program components that generalize subroutines for non-preemptive multitasking, by allowing multiple entry points for suspending and resuming execution at certain locations. Coroutines are well-suited for implementing more familiar program components such as cooperative tasks, exceptions, event loop, iterators, infinite lists and pipes. 协程是一种为了实现非抢占式多任务的程序组件,它会有多个进入点,在这些进入点可以挂起休眠和恢复执行。协程非常适合用来实现我们常见的一些程序组件,例如协作式任务、异常、事件循环、迭代器、无限列表和管道。 在我的理解中,协程本质上是一些程序的执行序列,它允许开发者使用它实现多任务协作完成某件事情。只是

Python程序中的协程操作-greenlet模块

本秂侑毒 提交于 2020-02-04 12:12:08
目录 Python程序中的协程操作-greenlet模块 一、安装模块 二、greenlet实现状态切换 三、效率对比 Python程序中的协程操作-greenlet模块 一、安装模块 安装:pip3 install greenlet 二、greenlet实现状态切换 from greenlet import greenlet def eat(name): print('%s eat 1' %name) g2.switch('randy') print('%s eat 2' %name) g2.switch() def play(name): print('%s play 1' %name) g1.switch() print('%s play 2' %name) g1=greenlet(eat) g2=greenlet(play) g1.switch('randy')#可以在第一次switch时传入参数,以后都不需要 randy eat 1 randy play 1 randy eat 2 randy play 2 三、效率对比 单纯的切换(在没有io的情况下或者没有重复开辟内存空间的操作),反而会降低程序的执行速度。 #顺序执行 import time def f1(): res = 1 for i in range(100000000): res += i def f2():

并发编程中一些问题

假如想象 提交于 2020-02-03 22:00:02
多线程就一定好吗?快吗?? 并发编程的目的就是为了能提高程序的执行效率提高程序运行速度,但是并发编程并不总是能提高程序运行速度的,而且并发编程可能会遇到很多问题,比如:内存泄漏、上下文切换、死锁还有受限于硬件和软件的资源闲置问题。 多线程就是几乎同时执行多个线程(一个处理器在某一个时间点上永远都只能是一个线程!即使这个处理器是多核的,除非有多个处理器才能实现多个线程同时运行)。CPU通过给每个线程分配CPU时间片来实现伪同时运行,因为CPU时间片一般很短很短,所以给人一种同时运行的感觉。 上下文切换 当前任务在执行完CPU时间片切换到另一个任务之前会先保存自己的状态,以便下次再切换会这个任务时,可以再加载这个任务的状态。 任务从保存到再加载的过程就是一次上下文切换。 上下文切换通常是计算密集型的。也就是说,它需要相当可观的处理器时间,在每秒几十上百次的切换中,每次切换都需要纳秒量级的时间。所以, 上下文切换对系统来说意味着消耗大量的 CPU 时间 ,事实上,可能是操作系统中时间消耗最大的操作。 Linux相比与其他操作系统(包括其他类 Unix 系统)有很多的优点,其中有一项就是,其上下文切换和模式切换的时间消耗非常少。 减少上下文切换 上下文切换又分为2种: 让步式上下文切换 和 抢占式上下文切换 。前者是指执行线程主动释放CPU,与锁竞争严重程度成正比,可通过 减少锁竞争

golang-协程理解

泄露秘密 提交于 2020-02-03 08:05:07
本文总结一下go协程的理解,如有错误望请指正。 网上都说协程是一种轻量级线程,线程又是一种轻量级的进程。这话在语言层面看来是没有错的,但它们的实现是不同的。 线程是cpu资源调度的最小单位。协程不由cpu进行调度,由应用程序进行调度,也就是由go进行调度。在go中,协程的调度也有专门的调度器。但go的协程调度器的复杂程度比cpu的线程调度器是要低许多的。 计算机进程/线程的运行是抢占式的,操作系统负责分配cpu执行时间给各个线程,当时间到达后,当前线程必须暂停进入睡眠,等待后续获得cpu执行时间再度恢复执行;当然线程也可以主动放弃cpu,进入睡眠,这一操作大多由程序员来控制。 协程实现原理 下面说下go中协程的实现原理,这些是我个人所知道的,错误之处望指正。 go中协程的实现原理还是基于线程的,大致由一个数据队列和多个线程实现。将一个个协程的代码放入数据队列,由go内部的线程去数据队列中拉取协程进行执行,协程本质还是运行在线程上的。go明面上并没有提供任何创建启动一个线程的方法,只提供了创建运行协程的方法。当用户创建的协程越来越多,线程处理不完时,go自己就会创建新的线程来执行协程。可以看到go本质上也是多线程的运行方式。但它与传统的一个请求一个线程的方式又有不同,在go中,http服务接受一个请求是创建一个协程来为这个请求服务的,可以看到,在资源利用方法