协程

8.15并发编程(四)

爱⌒轻易说出口 提交于 2019-11-27 13:46:43
一、进程池和线程池 1.什么是池   池可以理解是一种容器,它其实是降低了程序的运行效率但是提高了计算机的硬件安全,因为硬件的发展跟不上软件的发展速度 2.池的作用是什么   池的作用就是在保证计算机硬件安全的前提下,最大限度的利用计算机 3.进程池和线程池   进程池:我们所允许创建的最大进程数   线程池:我们在一个进程内所允许创建的最大的线程数 4.注意:   开进程和开线程都会消耗资源,但是两者对比来说开线程所消耗的资源最小,开销最小   进程池和线程池的本质都是在计算机能够承受的范围内最大限度的利用计算机 二、进程池、线程池的创建和异步回调 1.使用方法 from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor #创建池 pool = ThreadPoolExecutor(5) # 5 线程个数,也可以不传,默认是CPU个数乘以5 #pool = ProcessPoolExecutor() # 进程池不传参数,默认是当前cpu的个数 def task(n): print(n) time.sleep() #提交任务:异步提交 # pool.submit(task, 1) 朝线程池提交任务 #回调机制:pool.submit(task, 1).add_done_callback

GO的并发之道-Goroutine调度原理&Channel详解

霸气de小男生 提交于 2019-11-27 13:36:48
并发(并行),一直以来都是一个编程语言里的核心主题之一,也是被开发者关注最多的话题;Go语言作为一个出道以来就自带 『高并发』光环的富二代编程语言,它的并发(并行)编程肯定是值得开发者去探究的,而Go语言中的并发(并行)编程是经由goroutine实现的,goroutine是golang最重要的特性之一,具有使用成本低、消耗资源低、能效高等特点,官方宣称原生goroutine并发成千上万不成问题,于是它也成为Gopher们经常使用的特性。 一、goroutine简介 Golang被极度赞扬的是它的异步机制,也就是goroutine。goroutine使用方式非常的简单,只需使用go关键字即可启动一个协程, 并且它是处于异步方式运行,你不需要等它运行完成以后再执行以后的代码。 go func()//通过go关键字启动一个协程来运行函数 除去语法上的简洁,goroutine是一个协程,也就是比线程更节省资源,一个线程中可以有多个协程,而且goroutine被分配到多个CPU上运行,是真正意义上的并发。 go func()//通过go关键字启动一个协程来运行函数 二、goroutine内部原理 在介绍goroutine原理之前,先对一些关键概念进行介绍: 关键概念 并发 一个cpu上能同时执行多项任务,在很短时间内,cpu来回切换任务执行(在某段很短时间内执行程序a

【Python协程的实现】 -- 2019-08-16 19:03:17

一曲冷凌霜 提交于 2019-11-27 13:34: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,就会从应用程序级别(而非操作系统

【Python协程的实现】 -- 2019-08-16 18:56:05

一世执手 提交于 2019-11-27 13:31:22
原文: 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,就会从应用程序级别(而非操作系统

一个小事例,了解golang通道阻塞模式

删除回忆录丶 提交于 2019-11-27 12:30:54
在学习golang中,channel真的是让人捉摸不透的东西,本来我自以为我理解了协程阻塞的用法了,结果就下面这个小例子,我还是在打印输出后才搞明白到底怎么回事? 当然了,这也是我自身对协程这块不太熟造成的呀,另外,学习还真不能想当然,尤其是编程这块,真是要多实践,有时候你不经意的一点小举动,可能都会让你学到东西,甚至让你受益非浅的。 下面就是那个小例子,通过输出调试看结果后,也让我比以前更了解这个channel阻塞模式了。 package main import ( "fmt" "sync" ) var wg sync.WaitGroup var printChar chan int func prinNums() { defer wg.Done() for i:=0;i < 2; i++ { printChar <- 1111 fmt.Println(<-printChar) } } func printChars(){ defer wg.Done() for i:=0;i < 2; i++ { fmt.Println("阻1") fmt.Println(<-printChar) fmt.Println("阻2") fmt.Println("出来1") printChar <- 1222 fmt.Println("出来2") } } func main(){ printChar

进程池和线程池 协程 # 33

六眼飞鱼酱① 提交于 2019-11-27 11:13:45
day33进程池和线程池 0.内容回顾 1 """""" 2 """ 3 昨日内容回顾 4 """ 5 6 """ 7 1.TCP服务端实现并发 8 1.将不同的功能尽量拆分成不同的函数 9 拆分出来的功能可以被多个地方使用 10 1.将连续循环和通信循环拆分成不同的函数 11 2.将通信循环做成多线程 12 13 ps: 14 1.端口报错解决策略: 15 server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) 16 2.线程并发,在同一个端口下进行 17 进程并发不同端口快速切换,进程需要进行快速回收 18 19 """ 20 21 """ 22 2.GIL(全局解释器锁) 23 1.在CPython解释器才有GIL的概念,不是Python的特点 24 2.GIL也是一把互斥锁,将并发变为串行,牺牲了效率,但是提高了数据的安全性 25 26 ps: 27 1.针对不同的数据 应该使用不同的锁去处理 28 2.自己不要轻易的处理锁的问题 哪怕你知道acquire 和 release 29 当业务逻辑稍微复杂的一点情况下 极容易造成死锁 30 31 CPython中GIL锁的存在是因为Python的内存管理不是线程安全的 32 """ 33 """ 34 3.内存管理 35 1.引用计数:值与变量的绑定关系的个数 36

协程与IO模型

眉间皱痕 提交于 2019-11-27 11:10:52
一、协程介绍 协程:是单线程下的并发,又称微线程,纤程。英文名Coroutine。一句话说明什么是线程: 协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的 需要强调: 1. python的线程属于内核级别的,即由操作系统控制调度(如单线程遇到io或执行时间过长就会被迫交出cpu执行权限,切换其他线程运行)2. 单线程内开启协程,一旦遇到io,自己通过代码控制切换,以此来提升效率;给操作系统感觉这个线程没有没有任何的IO(!!!非io操作的切换与效率无关) 二、协程优缺点及特点 对比操作系统控制线程的切换,用户在单线程内控制协程的切换 优点如下: 1. 协程的切换开销更小,属于程序级别的切换,操作系统完全感知不到,因而更加轻量级 2. 单线程内就可以实现并发的效果,最大限度地利用cpu 缺点如下: 1. 协程的本质是单线程下,无法利用多核,可以是一个程序开启多个进程,每个进程内开启多个线程,每个线程内开启协程 2. 协程指的是单个线程,因而一旦协程出现阻塞,将会阻塞整个线程 总结协程特点: 1.必须在只有一个单线程里实现并发 2.修改共享数据不需加锁 3.用户程序里自己保存多个控制流的上下文栈 4.附加:一个协程遇到IO操作自动切换到其它协程(如何实现检测IO,yield、greenlet都无法实现,就用到了gevent模块(select机制)) 切换

协程

半世苍凉 提交于 2019-11-27 11:06:01
协程具有极高的执行效率,因为子程序切换不是线程切换,而是由程序控制, 没有线程切换的开销,和多线程比,线程数量越多,性能优势越明显。 因为只有一个线程,不存在同时写变量冲突,在协程中控制共享资源只需要判断状态, 不必加锁,故执行效率比多线程高。 协程是一个线程执行,使用多进程+协程,可充分利用多核CPU,获得极佳性能。 【1】yield实现协程(生产者消费者) Python通过yield提供了对协程的基本支持,但是不完全。 1 import time 2 3 def consumer(name): 4 print("准备") 5 while True: 6 result = yield 7 print("[%s] 消费 %s" % (name,result)) 8 #time.sleep(1) 9 10 def producer(): 11 12 r = con1.__next__() 13 r = con2.__next__() 14 n = 0 15 while 1: 16 time.sleep(1) 17 print("\生产者: %s and %s" %(n,n+1)) 18 con1.send(n) #发送给yield,result得到此值。 19 con2.send(n+1) 20 n +=2 21 22 23 if __name__ == '__main__': 24

进程池 协程 与I/O模型

那年仲夏 提交于 2019-11-27 11:04:49
一.进程池与线程池 进程池:限制进程创建的数量,使用时直接从进程池,获取空闲进程去执行任务,减少创建和销毁进程带来的时间消耗;如果进程的数量没有达到最大数量,且没有空闲进程去执行     任务,就会再创建一个新的进程,放入进程池去执行任务;如果进程池中的进程数量达到最大数量,没有空闲进程去,这是任务需要等待某个进程成为空闲进程之后,     再去执行任务。 from concurrent.futures import ProcessPoolExecutor import time import os # 池子中创建的进程/线程创建会被保存在进程/线程池中 # 会调用进程/线程池中的进程/线程去执行任务 # 节省了反复开辟进程/线程的资源 pool = ProcessPoolExecutor() # 默认是当前计算机cpu的个数 def task(n): print(n,os.getpid()) # 查看当前进程号 time.sleep(2) if __name__ == '__main__': for i in range(20): res = pool.submit(task,i) View Code ps:当进程池满后,没有kill进程的情况下,会使用进程池中的进程去执行任务,不会再去创建新的进程。 线程池:同进程池概念类似。 from concurrent.futures

5,线程池,进程池,协程,IO模型

好久不见. 提交于 2019-11-27 11:03:39
今日内容: 1,线程池 2,进程池 3,协程 4,IO 模型服务端要满足这三个条件: 1,24小时不间断的提供服务 2,能够支持高并发 3,要有固定的IP地址和端口在服务端这个地方会出现阻塞态情况: 阻塞IO 操作有: 1,链接循环 2,通信循环单线程实现高并发思路: 为了更好的提高程序的运行效率,即实现高并发,让服务端同时能够接受多个客户端的消息 所以一般在服务端会把,连接循环和通信循环封装为两个不同的函数方法, 这样当一个客户端与服务端进行通信时,服务端的连接循环可以和其他客户端进行连接, 不要等待,从而提高了效率,可以利用单线程来完成高并发,即来一个客户端就开一个线程, 每来一个客户端就开一个线程,看上去像高并发! 案列: import socket from threading import Thread def server1(): server = socket.socket() server.bind(('127.0.0.1', 1688)) server.listen(5) server2(server) def task(conn): 通信循环 while True: try: data = conn.recv(1024) # 在这里会形成阻塞,等待对客户端发消息过来 # 不加,就会形成阻塞,一直等待对方发消息过来 if len(data) == 0:break