通过生成器yield实现单线程的情况下实现并发运算效果(异步IO的雏形)

一、协程:

1、生成器只有在调用时才会生成相应的数据

2、调用方式有 " str__next__.()   str.send() ",

3、并且每调用一次就产生一个值调用到最后一个值后会报错

4、报错可用try和except做异常处理

注意:

next:是直接调用yield,并不会传值。

send:是调用并直接传值给yield。

 1 #!/usr/bin/env python
 2 # -*- coding:utf8 -*-
 3 # Author:Dong Ye
 4
 5
 6 ‘‘‘
 7 定义两个模型:
 8 一个是生产包子的。(生成器)
 9 另一个是吃包子的。(迭代器)
10
11 这段功能实现了异步IO的雏形,也是一个简单的协程处理方式。
12 协程的特点:实际是串行方式分开执行的,但由于运行效果快,给人的感觉像是并行。
13 因此,协程也叫作:单线程下的并行执行效果。
14 协程是包含在线程里的一个单位,线程时进程的一个单位。
15 例如:enginx在异步单线程下,比多线程要快好多倍,也就是这种效果。
16 ‘‘‘
17
18 import time
19
20
21 #吃包子的
22 def consumer(name):
23     print(‘%s 准备吃包子了!‘ % name)
24     while True:
25         baozi = yield
26         print("包子[%s]来了。被[%s]吃了!" %(baozi,name))
27
28
29 #生产包子的
30 def producer(name):
31     #先定义2个协程(消费者)#将函数变成生成器
32     c1 = consumer(‘A‘)   #2个消费者
33     c2 = consumer(‘B‘)   #相当于2个协程(进程,线程,协程)
34     #开始调用生成器初始化(准备吃包子)
35     c1.__next__()     #开始调用生成器,只有next的时候才会到yield进行下一个操作
36     c2.__next__()
37     print(‘老子开始吃包子拉!‘)
38     #循环的次数,每次循环都会传值给生成器(产生什么样的包子)
39     for i in range(10):
40         time.sleep(1)
41         print("做了一个包子,分2半,一人一半")
42         c1.send(i) #包子的类型
43         c2.send(i)
44
45
46 producer("alex")
47
48
49
50 ‘‘‘
51 #手动做包子:
52 c = consumer("dy")
53 c.__next__()
54 #c.__next__()
55
56 b1 = "韭菜馅"
57 c.send(b1)     #调用+传值
58 #c.__next__()  #只调用,不传值
59 ‘‘‘
60
61
62
63
64 显示结果:
65 A 准备吃包子了!
66 B 准备吃包子了!
67 老子开始吃包子拉!
68 做了一个包子,分2半,一人一半  #任务1
69 包子[0]来了。被[A]吃了!      #任务2
70 包子[0]来了。被[B]吃了!      #任务3
71 做了一个包子,分2半,一人一半
72 包子[1]来了。被[A]吃了!
73 包子[1]来了。被[B]吃了!
74 做了一个包子,分2半,一人一半
75 包子[2]来了。被[A]吃了!
76 包子[2]来了。被[B]吃了!
77 做了一个包子,分2半,一人一半
78 包子[3]来了。被[A]吃了!
79 包子[3]来了。被[B]吃了!
80 做了一个包子,分2半,一人一半
81 包子[4]来了。被[A]吃了!
82 包子[4]来了。被[B]吃了!
83 做了一个包子,分2半,一人一半
84 包子[5]来了。被[A]吃了!
85 包子[5]来了。被[B]吃了!
86 做了一个包子,分2半,一人一半
87 包子[6]来了。被[A]吃了!
88 包子[6]来了。被[B]吃了!
89 做了一个包子,分2半,一人一半
90 包子[7]来了。被[A]吃了!
91 包子[7]来了。被[B]吃了!
92 做了一个包子,分2半,一人一半
93 包子[8]来了。被[A]吃了!
94 包子[8]来了。被[B]吃了!
95 做了一个包子,分2半,一人一半
96 包子[9]来了。被[A]吃了!
97 包子[9]来了。被[B]吃了!

协程的示例

原文地址:https://www.cnblogs.com/abobo/p/8110485.html

时间: 2024-10-15 19:56:41

通过生成器yield实现单线程的情况下实现并发运算效果(异步IO的雏形)的相关文章

2017/9/5的学习内容___通过yield实现在单线程的情况下实现并发运算的效果

之前的学习内容,由于没有申请开通博客,就没有分享,今天想分享一下学习内容:通过yield实现在单线程的情况下实现并发运算的效果 采用的是经典的生产消费者模型 定义了两个函数 Consumer与Producer 关于生成器标志yield : 如果用__next__访问,只是单纯调用yield :如果是send访问,不仅可以访问yield,也可以给yield赋值! 需求:一个人造包子:两个人吃包子: 代码如下: 1 # -*- coding:utf-8 -*- 2 # Author : 何子辰 3

理论铺垫:阻塞IO、非阻塞IO、IO多路复用/事件驱动IO(单线程高并发原理)、异步IO

完全来自:http://www.cnblogs.com/alex3714/articles/5876749.html 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一下本文的上下文. 本文讨论的背景是Linux环境下的network IO. 一 概念说明 在进行解释之前,首先要说明几个概念:- 用户空间和内核空间- 进程切换- 进程的阻塞- 文件描述符- 缓存 I/O 用户空间与内核空间 现在操作系统都是采用虚拟存储器,

python(十)下:事件驱动与 阻塞IO、非阻塞IO、IO多路复用、异步IO

上节的问题: 协程:遇到IO操作就切换. 但什么时候切回去呢?怎么确定IO操作完了? 一.事件驱动模型介绍 通常,我们写服务器处理模型的程序时,有以下几种模型: (1)每收到一个请求,创建一个新的进程,来处理该请求: (2)每收到一个请求,创建一个新的线程,来处理该请求: (3)每收到一个请求,放入一个事件列表,让主进程通过非阻塞I/O方式来处理请求 第三种就是协程.时间驱动的方式,一般普遍认为第(3)种方式是大多数网络服务器采用的方式 论事件驱动模型 在UI编程中,,常常要对鼠标点击进行相应,

零基础学python-19.5 重放迭代器:生成器yield

这一章节我们来讨论一些生成器yield 1.yield的特性:延迟结果创建 * 生成器函数:也是使用def定义,但是使用yield返回,而且每次返回只是返回一个结果,在每次产生结果之间挂起和继续它们的状态(就是当返回有三个结果,第一个结果返回了,但是第二个结果没有返回,但是由于是yield,它记录下返回第一个结果时所有作用域以及变量的状态,因此,在当需要返回第二个结果的时候,它将会继续刚才的状态计算下去). >>> def test(N): for x in range(N): yiel

如何处理高并发情况下的DB插入

插入数据库,在大家开发过程中是很经常的事情,假设我们有这么一个需求: 1.  我们需要接收一个外部的订单,而这个订单号是不允许重复的 2.  数据库对外部订单号没有做唯一性约束 3.  外部经常插入相同的订单,对于已经存在的订单则拒绝处理 对于这个需求,很简单我们会用下面的代码进行处理(思路:先查找数据库,如果数据库存在则直接退出,否则插入) package com.yhj.test; import com.yhj.dao.OrderDao; import com.yhj.pojo.Order;

python中的生成器yield

生成器yield:使用yield语句 可以让函数生成一个结果序列而不仅仅是一个值 def  countdow(n):      print("Start!");      while n>0:           yield n;           n -= 1; c = countdow(5); print(c.__next__())  print(c.__next__()) 输出结果: Start! 54__next__()方法使生成器函数一直运行到下一条yield语句为止

高并发情况下Redis 的可用性测试与分析及部署架构说明

一.Redis AOF模式设置 修改配置文件redis.conf参数: appendonly yes # appendfsync always appendfsync everysec # appendfsync no 二.测试方法 创建多线程,其中每一个线程执行一个无限循环向Redis 发送set key-value命令,由于处理器执行一次循环操作的速度非常快,因此这样每一个线程都模拟了一个多并发的情况. <span style="font-size:18px;">cla

java 哪些情况下会使对象锁释放

Java_多线程_锁释放 问:Java多线程运行环境中,在哪些情况下会使对象锁释放?答:由于等待一个锁的线程只有在获得这把锁之后,才能恢复运行,所以让持有锁的线程在不再需要锁的时候及时释放锁是很重要的.在以下情况下,持有锁的线程会释放锁:(1)执行完同步代码块,就会释放锁.(synchronized)(2)在执行同步代码块的过程中,遇到异常而导致线程终止,锁也会被释放.(exception)(3)在执行同步代码块的过程中,执行了锁所属对象的wait()方法,这个线程会释放锁,进        入

WebClient在多线程、使用代理情况下 socket closed 问题的一个解决办法[htmlunit]

通过 WebClient 的内置浏览器,可以执行页面抓取工作,有时可能需要设置代理,WebClient webClient = new WebClient(BrowserVersion.x);webClient.setProxyConfig(ProxyConfig pc);在单线程情况下,使用这样创建的webClient不会有问题:客户端到代理服务器的连接能够很有次序的建立.关闭. 考虑这样的情况:多个线程并发地访问 WebClient,可能就会报下面的异常: [Thread-7] DEBUG