协程

day38_步入百万年薪的第三十八天——线程queue、事件event、协程

若如初见. 提交于 2019-11-28 22:57:43
day38 线程queue 多线程抢占资源 只能让其串行——用到互斥锁 线程queue 队列——先进先出(FIFO) import queue q = queue.Queue(3) q.put(1) q.put(2) q.put(3) # q.put(4) # 阻塞等其他进程或者线程来拿 print(q.get()) print(q.get()) print(q.get()) # print(q.get(block=False)) # 没有值就直接报错 # q.get(timeout=2) # 阻塞2s,还没有值直接报错 堆栈——先进后出(LIFO) import queue q = queue.LifoQueue(4) q.put(1) q.put(2) q.put("alex") q.put("太白") print(q.get()) print(q.get()) print(q.get()) print(q.get()) 结果: 太白 alex 2 1 优先级队列——自己设置优先级 import queue q = queue.PriorityQueue(4) q.put((5, "元宝")) q.put((-2, "狗狗")) q.put((0, "2李业")) q.put((0, "1刚哥")) print(q.get()) print(q.get()) print(q

Python之并发编程(九)线程队列、Event事件、协程

回眸只為那壹抹淺笑 提交于 2019-11-28 22:53:51
线程队列、Event事件、协程 线程队列 先进先出示例: import queue #不需要通过threading模块里面导入,直接import queue就可以了,这是python自带的 #用法基本和我们进程multiprocess中的queue是一样的 q=queue.Queue() q.put('first') q.put('second') q.put('third') # q.put_nowait() #没有数据就报错,可以通过try来搞 print(q.get()) print(q.get()) print(q.get()) # q.get_nowait() #没有数据就报错,可以通过try来搞 ''' 结果(先进先出): first second third ''' 先进后出(Lifo堆栈)示例: import queue q=queue.LifoQueue() #队列,类似于栈,栈我们提过吗,是不是先进后出的顺序啊 q.put('first') q.put('second') q.put('third') # q.put_nowait() print(q.get()) print(q.get()) print(q.get()) # q.get_nowait() ''' 结果(后进先出): third second first ''' 优先级队列示例 import

php的协程

白昼怎懂夜的黑 提交于 2019-11-28 22:37:19
有关迭代生成器的内容在 这篇博客中 协程 协程的支持是在迭代生成器的基础上, 增加了可以回送数据给生成器的功能(调用者发送数据给被调用的生成器函数). 这就把生成器到调用者的单向通信转变为两者之间的双向通信. 传递数据的功能是通过迭代器的send()方法实现的. 下面的logger()协程是这种通信如何运行的例子: <?php function logger($fileName) { $fileHandle = fopen($fileName, 'a'); while (true) { fwrite($fileHandle, yield . "\n"); } } $logger = logger(__DIR__ . '/log'); $logger->send('Foo'); $logger->send('Bar') ?> 正如你能看到, 这儿yield没有作为一个语句来使用, 而是用作一个表达式, 即它能被演化成一个值. 这个值就是调用者传递给send()方法的值 . 在这个例子里, yield表达式将首先被”Foo”替代写入Log, 然后被”Bar”替代写入Log. 上面的例子里演示了yield作为接受者, 接下来我们看如何同时进行接收和发送的例子: <?php function gen() { $ret = (yield 'yield1'); /

进程,线程池 ,同步异步

梦想的初衷 提交于 2019-11-28 22:31:15
进程池,线程池 以时间换空间,控制进程,线程开启的数量 进程池与cpu一一对应是并行 线程池是并发:一个容器,这个容器限制住你开启线程(进程)的数量,比如4个,第一次肯定只能变更发的处理4个任务,只要有任务完成,线程马上就会接下一个人任务 以时间换空间,控制进程,线程开启的数量 进程池与cpu一一对应是(并行)或并行加并发 线程池是并发:一个容器,这个容器限制住你开启线程(进程)的数量,比如4个,第一次肯定只能变更发的处理4个任务,只要有任务完成,线程马上就会接下一个人任务 以时间换空间 from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor def fun(): print(1) t=ThreadPoolExecutor()#实例化一个进程池对象 t.submit(fun)#用submit开启一个进程池 基于线程池的服务端 from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor import socket import os import time import random def communicate(conn, addr): while 1: # # try: from_client_data = conn

并发编程:协程

瘦欲@ 提交于 2019-11-28 20:18:17
一 引子   基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此需要先看下并发的本质:切换+保存状态 ​ cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制),一种情况是该任务发生了阻塞,另外一种情况是该任务计算的时间过长或有一个优先级更高的程序替代了它   协程本质上就是一个线程,以前线程任务的切换是由操作系统控制的,遇到I/O自动切换,用协程的目的就是较少操作系统切换的开销(开关线程,创建寄存器、堆栈等,在他们之间进行切换等),在自己的程序里面来控制任务的切换。     ps:在介绍进程理论时,提及进程的三种执行状态,而线程才是执行单位,所以也可以将上图理解为线程的三种状态   一:其中第二种情况并不能提升效率,只是为了让cpu能够雨露均沾,实现看起来所有任务都被“同时”执行的效果,如果多个任务都是纯计算的,这种切换反而会降低效率。为此可以基于yield来验证。yield本身就是一种在单线程下可以保存任务运行状态的方法: #1 yiled可以保存状态,yield的状态保存与操作系统的保存线程状态很像,但是yield是代码级别控制的,更轻量级 #2 send可以把一个函数的结果传给另外一个函数,以此实现单线程内程序之间的切换 import time def func1(): for i in range(11

多线程补充以及协程

自作多情 提交于 2019-11-28 18:47:59
多线程补充以及协程 1.线程队列 线程队列用法与进程队列一样 import queue #先进先出 q = queue.Queue() q.put(1) q.put(2) q.put(3) print(q.get()) # 1 print(q.get()) # 2 print(q.get()) # 3 print(q.get(block=False)) # 取不到值直接报错 q.get(timeout=2) # 阻塞2秒,还没有值直接报错 import queue # 后进先出 LiFo 堆栈 q = queue.LifoQueue(3) q.put(1) q.put(2) q.put('alex') print(q.get()) # 'alex' print(q.get()) # 2 print(q.get()) # 1 import queue # 优先级队列 q = queue.PriorityQueue q.put((5,'alex')) q.put((-2,'七七')) q.put((0,'赫赫')) print(q.get()) # (-2,'七七') print(q.get()) # (0,'赫赫') print(q.get()) # (5,'alex') #put进入一个元组,元组的第一个元素是优先级(通常是数字,也可以是非数字之间的比较),数字越小优先级越高

百万年薪python之路 -- 并发编程之 协程

拜拜、爱过 提交于 2019-11-28 18:42:09
协程 一. 协程的引入 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态   cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制),一种情况是该任务发生了阻塞,另外一种情况是该任务计算的时间过长或有一个优先级更高的程序替代了它   协程本质上就是一个线程,以前线程任务的切换是由操作系统控制的,遇到I/O自动切换,现在我们用协程的目的就是较少操作系统切换的开销(开关线程,创建寄存器、堆栈等,在他们之间进行切换等),在我们自己的程序里面来控制任务的切换。     ps:在介绍进程理论时,提及进程的三种执行状态,而线程才是执行单位,所以也可以将上图理解为线程的三种状态 一:其中上图的第二种情况并不能提升效率,只是为了让cpu能够雨露均沾,实现看起来所有任务都被“同时”执行的效果,如果多个任务都是纯计算的,这种切换反而会降低效率。为此我们可以基于yield来验证。yield本身就是一种在单线程下可以保存任务运行状态的方法,我们来简单复习一下: #1 yiled可以保存状态,yield的状态保存与操作系统的保存线程状态很像,但是yield是代码级别控制的,更轻量级 #2 send可以把一个函数的结果传给另外一个函数,以此实现单线程内程序之间的切换

python_高级进阶(5)协程_事件

孤人 提交于 2019-11-28 18:20:51
线程queue 第一种、先进先出 import queue q = queue.Queue(3) q.put(1) q.put(2) q.put(3) q.put(4) print(q.get()) print(q.get()) print(q.get()) print(q.get(block=False)) q.get(timeout=2) # 阻塞2s 还没有值直接报错 结果: #1 #2 #3 ##第二种、后进先出 Lifo 堆栈 q = queue.LifoQueue(4) q.put(1) q.put(2) q.put('alex') q.put('太白') print(q.get()) print(q.get()) print(q.get()) print(q.get()) 结果: 太白 alex 2 1 第三种、优先级队列 q = queue.PriorityQueue(4) q.put((5, '元宝')) q.put((-2,'狗狗')) q.put((0, '李业')) print(q.get()) print(q.get()) print(q.get()) 结果: (-2, '狗狗') (0, '李业') (5, '元宝') 事件event 开启两个线程,一个线程运行到中间的某个阶段,触发另一个线程执行,两个线程增加了耦合性 版本一

Go语言的几大优势和特性

雨燕双飞 提交于 2019-11-28 17:49:15
要说起GO语言的优势,我们就得从GO语言的历史讲起了…… 本文由 腾讯技术工程官方号 发表在 腾讯云+社区 2007年,受够了C++煎熬的Google首席软件工程师Rob Pike纠集Robert Griesemer和Ken Thompson两位牛人,决定创造一种新语言来取代C++, 这就是Golang。出现在21世纪的GO语言,虽然不能如愿对C++取而代之,但是其近C的执行性能和近解析型语言的开发效率以及近乎于完美的编译速度,已经风靡全球。特别是在云项目中,大部分都使用了Golang来开发,不得不说,Golang早已深入人心。而对于一个没有历史负担的新项目,Golang或许就是个不二的选择。 被称为GO语言之父的Rob Pike说,你是否同意GO语言,取决于你是认可少就是多,还是少就是少(Less is more or less is less)。Rob Pike以一种非常朴素的方式,概括了GO语言的整个设计哲学--将简单、实用体现得淋漓尽致。 很多人将GO语言称为21世纪的C语言,因为GO不仅拥有C的简洁和性能,而且还很好的提供了21世纪互联网环境下服务端开发的各种实用特性,让开发者在语言级别就可以方便的得到自己想要的东西。 发展历史 2007年9月,Rob Pike在Google分布式编译平台上进行C++编译,在漫长的等待过程中,他和Robert

浅析runtime包中的三个方法Gosched、Goexit、GOMAXPROCS

你。 提交于 2019-11-28 17:28:51
Gosched 暂停当前goroutine,使其他goroutine先行运算。只是暂停,不是挂起,当时间片轮转到该协程时,Gosched()后面的操作将自动恢复 未使用Gosched的代码 package main import ( "fmt" ) func main() { go output("goroutine 2") output("goroutine 1") } func output(s string){ for i:=0;i<3;i++{ fmt.Println(s) } } 输出 goroutine 1 goroutine 1 goroutine 1 结论: 还没等到子协程执行,主协程就已经执行完退出了,子协程将不再执行,所以打印的全部是主协程的数据。当然,实际上这个执行结果也是不确定的,只是大概率出现以上输出,因为主协程和子协程间并没有绝对的顺序关系 使用Gosched的代码 package main import ( "fmt" "runtime" ) func main() { go output("goroutine 2") runtime.Gosched() output("goroutine 1") } func output(s string){ for i:=0;i<3;i++{ fmt.Println(s) } } 输出 goroutine 2