协程

并发编程小结

亡梦爱人 提交于 2019-11-30 09:23:37
一、到底什么是线程?什么是进程? Python自己没有这玩意,Python中调用的操作系统的线程和进程。 二、Python多线程情况下: 计算密集型操作:效率低,Python内置的一个全局解释器锁,锁的作用就是保证同一时刻一个进程中只有一个线程可以被cpu调度,多线程无法利用多核优势,可以通过多进程方式解决,但是比较浪费资源。 IO操作:效率高 三、Python多进程的情况下: 计算密集型操作:效率高(浪费资源),不得已而为之。 IO操作:效率高(浪费资源) 四、为什么有这把GIL锁? Python语言的创始人在开发这门语言时,目的快速把语言开发出来,如果加上GIL锁(C语言加锁),切换时按照100条字节指令来进行线程间的切换。 五、Python中线程和进程(GIL锁) GIL锁,全局解释器锁。用于限制一个进程中同一时刻只有一个线程被cpu调度。 扩展:默认GIL锁在执行100个cpu指令(过期时间)。 查看GIL切换的指令个数 import sys v1 = sys。getcheckinterval() print(v1) 六、为什么要创建线程? 由于线程是cpu工作的最小单元,创建线程可以利用多核优势实现并行操作(Java/C#)。 注意: 线程是为了工作。 七、为什么要创建进程? 进程和进程之间做数据隔离(Java/C#)。 注意: 进程是为了提供环境让线程工作。 八

协程基础

泄露秘密 提交于 2019-11-30 06:28:00
协程基础 一、引言 之前我们学习了线程、进程的概念,了解了在操作系统中进程是资源分配的最小单位,线程是CPU调度的最小单位。按道理来说我们已经算是把CPU的利用率提高很多了。但是我们知道无论是创建多进程还是创建多线程来解决问题,都要消耗一定的时间来创建进程、创建线程、以及管理他们之间的切换。 随着我们对于效率的追求不断提高,基于单线程来实现并发又成为一个新的课题,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发。这样就可以节省创建线进程所消耗的时间。 为此我们需要先回顾下 并发的本质 : 切换+保存状态 。 CPU正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制),一种情况是该任务发生了阻塞,另外一种情况是该任务计算的时间过长。 ps:在介绍进程理论时,提及进程的三种执行状态,而线程才是执行单位,所以也可以将上图理解为线程的三种状态。 一:其中第二种情况并不能提升效率,只是为了让cpu能够雨露均沾,实现看起来所有任务都被“同时”执行的效果,如果多个任务都是纯计算的,这种切换反而会降低效率。 为此我们可以基于yield来验证。yield本身就是一种在单线程下可以保存任务运行状态的方法,我们来简单复习一下: yiled可以保存状态,yield的状态保存与操作系统的保存线程状态很像,但是yield是代码级别控制的,更轻量级

协程基础及其创建和使用方法

ぃ、小莉子 提交于 2019-11-30 05:54:18
一、引言 之前我们学习了线程、进程的概念,了解了在操作系统中进程是资源分配的最小单位,线程是CPU调度的最小单位。按道理来说我们已经算是把cpu的利用率提高很多了。但是我们知道无论是创建多进程还是创建多线程来解决问题,都要消耗一定的时间来创建进程、创建线程、以及管理他们之间的切换。 随着我们对于效率的追求不断提高,基于单线程来实现并发又成为一个新的课题,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发。这样就可以节省创建线进程所消耗的时间。 所以,产生协程的概念是为了实现: 单线程下实现并发 为此我们需要先回顾下并发的本质:切换+保存状态。 多线程实现并发:cpu正在运行一个任务(线程),会在两种情况下切走去执行其他的任务(切换由操作系统强制控制):,一种情况是该任务发生了阻塞,另外一种情况是该任务计算的时间过长。 如果是做纯计算任务的切换,这种切换反而会降低效率。 先在串行下执行计算任务: import time def eat(): print('eat 1') # 疯狂计算的时候没有io(计算密集) time.sleep(2) for i in range(100000000): i += 1 def play(): print('play 1') # 疯狂的计算的时候没有io(计算密集) time.sleep(3) for i in range

多任务实现-协程

自古美人都是妖i 提交于 2019-11-30 05:39:45
协程 协程,又称微线程,纤程。英文名Coroutine。 协程是啥 首先我们得知道协程是啥?协程其实可以认为是比线程更小的执行单元。 为啥说他是一个执行单元,因为他自带CPU上下文。这样只要在合适的时机, 我们可以把一个协程 切换到另一个协程。 只要这个过程中保存或恢复 CPU上下文那么程序还是可以运行的。 通俗的理解:在一个线程中的某个函数,可以在任何地方保存当前函数的一些临时变量等信息,然后切换到另外一个函数中执行,注意不是通过调用函数的方式做到的,并且切换的次数以及什么时候再切换到原来的函数都由开发者自己确定 协程和线程差异 那么这个过程看起来比线程差不多。其实不然, 线程切换从系统层面远不止保存和恢复 CPU上下文这么简单。 操作系统为了程序运行的高效性每个线程都有自己缓存Cache等等数据,操作系统还会帮你做这些数据的恢复操作。 所以线程的切换非常耗性能。但是协程的切换只是单纯的操作CPU的上下文,所以一秒钟切换个上百万次系统都抗的住。 协程的问题 但是协程有一个问题,就是系统并不感知,所以操作系统不会帮你做切换。 那么谁来帮你做切换?让需要执行的协程更多的获得CPU时间才是问题的关键。 例子 目前的协程框架一般都是设计成 1:N 模式。所谓 1:N 就是一个线程作为一个容器里面放置多个协程。 那么谁来适时的切换这些协程?答案是有协程自己主动让出CPU

Gevent高并发网络库精解

不羁的心 提交于 2019-11-30 05:39:34
进程 线程 协程 异步 并发编程(不是并行)目前有四种方式:多进程、多线程、协程和异步。 多进程编程在python中有类似C的os.fork,更高层封装的有multiprocessing标准库 多线程编程python中有Thread和threading 异步编程在linux下主+要有三种实现select,poll,epoll 协程在python中通常会说到yield,关于协程的库主要有greenlet,stackless,gevent,eventlet等实现。 进程 不共享任何状态 调度由操作系统完成 有独立的内存空间(上下文切换的时候需要保存栈、cpu寄存器、虚拟内存、以及打开的相关句柄等信息,开销大) 通讯主要通过信号传递的方式来实现(实现方式有多种,信号量、管道、事件等,通讯都需要过内核,效率低) 线程 共享变量(解决了通讯麻烦的问题,但是对于变量的访问需要加锁) 调度由操作系统完成(由于共享内存,上下文切换变得高效) 一个进程可以有多个线程,每个线程会共享父进程的资源(创建线程开销占用比进程小很多,可创建的数量也会很多) 通讯除了可使用进程间通讯的方式,还可以通过共享内存的方式进行通信(通过共享内存通信比通过内核要快很多) 协程 调度完全由用户控制 一个线程(进程)可以有多个协程 每个线程(进程)循环按照指定的任务清单顺序完成不同的任务(当任务被堵塞时,执行下一个任务

124 并发编程小结

不羁岁月 提交于 2019-11-30 03:37:01
目录 一、到底什么是线程?什么是进程? 二、Python多线程情况下: 三、Python多进程的情况下: 四、为什么有这把GIL锁? 五、Python中线程和进程(GIL锁) 六、为什么要创建线程? 七、为什么要创建进程? 八、进程和线程的区别? 九、线程创建的越多越好吗? 十、生产者消费者模型解决了什么问题? 十一、Lock和RLock的区别? 十二、进程和线程以及协程的区别? 十三、IO多路复用作用? 十四、socket默认是否是阻塞的?阻塞体现在哪里? 十五、什么是异步非阻塞? 十六、什么是同步阻塞? 十七、什么是协程? 十八、协程可以提高并发吗? 十九、提高并发方案: 二十、单线程提供并发 20.1 基于IO多路复用+socket非阻塞 20.2 协程+IO切换:gevent 20.3 基于事件循环的异步 20.3.1 方法一 20.3.2 方法二 20.4 基于事件循环的异步非阻塞框架 一、到底什么是线程?什么是进程? Python自己没有这玩意,Python中调用的操作系统的线程和进程。 二、Python多线程情况下: 计算密集型操作:效率低,Python内置的一个全局解释器锁,锁的作用就是保证同一时刻一个进程中只有一个线程可以被cpu调度,多线程无法利用多核优势,可以通过多进程方式解决,但是比较浪费资源。 IO操作:效率高 三、Python多进程的情况下:

协程

谁说胖子不能爱 提交于 2019-11-30 03:33:12
协程 python的线程用的是操作系统原生的线程 协程 :单线程下实现并发 ​ 并发:切换+保存状态 ​ 多线程:操作系统帮你实现的,如果遇到io切换,执行时间过长也会切换,实现一个雨露均沾的效果. 什么样的协程是有意义的? 遇到io切换的时候才有意义 具体: ​ 协程概念本质是程序员抽象出来的,操作系统根本不知道协程存在,也就说来了一个线程我自己遇到io 我自己线程内部直接切到自己的别的任务上了,操作系统跟本发现不了,也就是实现了单线程下效率最高. 优点: ​ 自己控制切换要比操作系统切换快的多 缺点: ​ 对比多线程 ​ 自己要检测所有的io,但凡有一个阻塞整体都跟着阻塞 ​ 对比多进程 ​ 无法利用多核优势 为什么要有协程(遇到io切换)? ​ 自己控制切换要比操作系统切换快的多.降低了单个线程的io时间 #简单举例 import time def eat(): print('eat 1') # 疯狂的计算呢没有io time.sleep(2) # for i in range(100000000): # i+1 def play(): print('play 1') # 疯狂的计算呢没有io time.sleep(3) # for i in range(100000000): # i+1 play() eat() # 5s #通过yield实现协程 import time

day40学习整理-并发编程

社会主义新天地 提交于 2019-11-30 03:32:01
目录 2019/09/19 学习整理 并发编程 线程queue 一、先进先出 二、后进先出 三、存储数据时可设置优先级的队列 四、其他用法 线程定时器 进程池和线程池 Python标准模块——concurrent.futures 一、ProcessPoolExecutor 与 ThreadPoolExecutor 二、回调函数 协程 一、什么是协程 二、协程操作-gevent模块 2019/09/19 学习整理 并发编程 线程queue queue队列:使用 import queue ,用法与进程Queue一样 一、先进先出 import queue q=queue.Queue() q.put('first') q.put('second') q.put('third') print(q.get()) print(q.get()) print(q.get()) ''' 结果(先进先出): first second third ''' 二、后进先出 import queue q=queue.LifoQueue() q.put('first') q.put('second') q.put('third') print(q.get()) print(q.get()) print(q.get()) ''' 结果(后进先出): third second first ''' 三

python爬虫之线程池和进程池

天涯浪子 提交于 2019-11-30 03:19:40
python爬虫之线程池和进程池 一、需求   最近准备爬取某电商网站的数据,先不考虑代理、分布式,先说效率问题(当然你要是请求的太快就会被封掉,亲测,400个请求过去,服务器直接拒绝连接,心碎),步入正题。一般情况下小白的我们第一个想到的是for循环,这个可是单线程啊。那我们考虑for循环直接开他个5个线程,问题来了,如果有一个url请求还没有回来,后面的就干等,这么用多线程等于没用,到处贴创可贴。 二、性能考虑   确定要用多线程或者多进程了,那我们到底是用多线程还是多进程,有些人对多进程和多线程有一定的偏见,就因为python的GIL锁,下面我们说一下这两个东西的差别。 三、多线程:   一般情况下我们启动一个.py文件,就等于启动了一个进程,一个进程里面默认有一个线程工作,我们使用的多线程的意思就是在一个进程里面启用多个线程。但问题来了,为什么要使用多线程呢?我知道启动一个进程的时候需要创建一些内存空间,就相当于一间房子,我们要在这个房子里面干活,你可以想一个人就等于一个线程,你房子里面有10个人的空间跟有20个人的空间,正常情况下是不一样的,因为我们知道线程和线程之间默认是可以通信的(进程之间默认是不可以通信的,不过可以用技术实现,比如说管道)。可以多线程为了保证计算数据的正确性,所以出现了GIL锁,保证同一时间只能有一个线程在计算。GIL锁你可以基本理解为

golang goroutine 协程原理

大城市里の小女人 提交于 2019-11-30 03:03:02
一、goroutine简介 goroutine是go语言中最为NB的设计,也是其魅力所在,goroutine的本质是协程,是实现并行计算的核心。goroutine使用方式非常的简单,只需使用go关键字即可启动一个协程,并且它是处于异步方式运行,你不需要等它运行完成以后在执行以后的代码。 go func()//通过go关键字启动一个协程来运行函数 二、goroutine内部原理 概念介绍 在进行实现原理之前,了解下一些关键性术语的概念。 并发 一个cpu上能同时执行多项任务,在很短时间内,cpu来回切换任务执行(在某段很短时间内执行程序a,然后又迅速得切换到程序b去执行),有时间上的重叠(宏观上是同时的,微观仍是顺序执行),这样看起来多个任务像是同时执行,这就是并发。 并行 当系统有多个CPU时,每个CPU同一时刻都运行任务,互不抢占自己所在的CPU资源,同时进行,称为并行。 进程 cpu在切换程序的时候,如果不保存上一个程序的状态(也就是我们常说的context--上下文),直接切换下一个程序,就会丢失上一个程序的一系列状态,于是引入了进程这个概念,用以划分好程序运行时所需要的资源。因此进程就是一个程序运行时候的所需要的基本资源单位(也可以说是程序运行的一个实体)。 线程 cpu切换多个进程的时候,会花费不少的时间,因为切换进程需要切换到内核态