分享流畅的python一书, coroutine 章节中的出租车仿真的例子.

 from  collections import namedtuple
import queue
import random
Event = namedtuple('Event', 'time process action') def taxi_simu(ident, trips, start_t = ):
time = yield Event(start_t, ident, 'get out of garage')
for i in range(trips):
time = yield Event(time, ident, 'pick up passenger')
time = yield Event(time, ident, 'passenger arrive destination') yield Event(time, ident, 'off duty, going home') class Emulator(object): def __init__(self, proc_mapping):
self.events = queue.PriorityQueue() # 保存排定事件的 PriorityQueue 对象,按时间正向排序。
self.process = dict(proc_mapping) # 获取的 procs_map 参数是一个字典(或其他映射),可是又从中构建一个字典,创建本地副本,
# 因为在仿真过程中,出租车回家后会从 self.procs 属性中移除,而我们不想修改用户传入的对象
'''
优先队列是离散事件仿真系统的基础构件:创建事件的顺序不定,放入这种队列之后,可以按照各个事件排定的时间顺序取出。
''' def comupte_duration(self, previous_action):
if 'get out of garage' in previous_action:
return random.randint(,)
elif 'pick up passenger' in previous_action:
return random.randint(,)
elif 'passenger arrive destination' in previous_action:
return random.randint(,)
else:
return
def run(self, end_time):
for _, process in sorted(self.process.items()): # 使用 sorted 函数获取 self.procs 中按键排序的元素;用不到键,因此赋值给 _。
first_event = next(process) # 调用 next(proc) 预激各个协程,向前执行到第一个 yield 表达式,做好接收数据的准备。产出一个 Event 对象。
self.events.put(first_event) # 把各个事件添加到 self.events 属性表示的 PriorityQueue 对象中。 simu_time = # 把 sim_time 变量(仿真钟)归零
while simu_time < end_time:
if self.events.empty(): # 如果队列中没有未完成的事件,退出主循环
print('empty events queue, all events done')
break current_event = self.events.get() # 获取优先队列中 time 属性最小的 Event 对象;这是当前事件(current_event)
simu_time, process_id, previous_action = current_event # 拆包 Event 对象中的数据。这一行代码会更新仿真钟 sim_time,对应于事件发生时的时间。
# 这通常是离散事件仿真:每次循环时仿真钟不会以固定的量推进,而是根据各个事件持续的时间推进
print('Taxi : ', process_id, process_id * ' ', current_event) # 显示 Event 对象,指明是哪辆出租车,并根据出租车的编号缩进
actived_process = self.process[process_id] # 从 self.procs 字典中获取表示当前活动的出租车的协程
next_time = simu_time + self.comupte_duration(previous_action)
try:
next_event = actived_process.send(next_time) # 把计算得到的时间发给出租车协程。协程会产出下一个事件(next_event),或者抛出 StopIteration 异常(完成时)
except StopIteration:
del self.process[process_id] # 如果抛出了 StopIteration 异常,从 self.procs 字典中删除那个协程
else:
self.events.put(next_event) # 否则,把 next_event 放入队列中
else:
msg = '=== end of simulation time : {} events are pending ==='
print(msg.format(self.events.qsize())) # 如果循环由于仿真时间到了而退出,显示待完成的事件数量(有时可能碰巧是零, 如 endtime 足够大,就不有 event pending, 都会处理完) if __name__ == '__main__':
taxi_num =
DEPARTURE_INTERVAL =
end_time =
taxis = {i: taxi_simu(i, (i+)*, i*DEPARTURE_INTERVAL)
for i in range(taxi_num)} simu = Emulator(taxis)
simu.run(end_time) '''
OUTPUT, Taxi : Event(time=, process=, action='get out of garage')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='get out of garage')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='get out of garage')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='get out of garage')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='get out of garage')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='off duty, going home')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='off duty, going home')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='off duty, going home')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='off duty, going home')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='pick up passenger')
Taxi : Event(time=, process=, action='passenger arrive destination')
Taxi : Event(time=, process=, action='off duty, going home')
empty events queue, all events done '''

coroutine - 示例的更多相关文章

  1. Coroutine in Java - Quasar Fiber实现--转载

    转自 https://segmentfault.com/a/1190000006079389?from=groupmessage&isappinstalled=0 简介 说到协程(Corout ...

  2. 【Unity3D基础教程】给初学者看的Unity教程(五):详解Unity3D中的协程(Coroutine)

    作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点[推荐].谢谢! 为什么需要协程 在游戏中有许多过程(Proc ...

  3. Lua 协程coroutine

    协程和一般多线程的区别是,一般多线程由系统决定该哪个线程执行,是抢占式的,而协程是由每个线程自己决定自己什么时候不执行,并把执行权主动交给下一个线程. 协程是用户空间线程,操作系统其存在一无所知,所以 ...

  4. Unity3D协同程序(Coroutine)

    摘要下: 1. coroutine, 中文翻译"协程".这个概念可能有点冷门,不过百度之,说是一种很古老的编程模型了,以前的操作系统里进程调度里用到过,现在操作系统的进程调度都是根 ...

  5. unity Dotween插件的简单介绍及示例代码

    unity里面做插值动画的插件有许多,比较常见的有itween.hotween.dotween.根据大家的反馈和实际体验来说,dotween插件在灵活性.稳定性.易用性上都十分突出.这里简单介绍下它的 ...

  6. (zt)Lua的多任务机制——协程(coroutine)

    原帖:http://blog.csdn.net/soloist/article/details/329381 并发是现实世界的本质特征,而聪明的计算机科学家用来模拟并发的技术手段便是多任务机制.大致上 ...

  7. 协程coroutine

    协程(coroutine)顾名思义就是“协作的例程”(co-operative routines).跟具有操作系统概念的线程不一样,协程是在用户空间利用程序语言的语法语义就能实现逻辑上类似多任务的编程 ...

  8. Coroutine,你究竟干了什么?

    一 引子 使用Unity已经有一段时间了,对于Component.GameObject之类的概念也算是有所了解,而脚本方面从一开始就选定了C#,目前来看还是挺明智的:Boo太小众,而且支持有限:JS( ...

  9. Lua 5.3 协程简单示例

    Lua 5.3 协程简单示例 来源 http://blog.csdn.net/vermilliontear/article/details/50547852 生产者->过滤器->消费者 模 ...

随机推荐

  1. HTML 图片(image) 左右滑动

    1.需求 需要用简单动画的形式将一组图片进行展示,图片数量不固定 2.效果如下: 3.思路 说到动画,首先想到使用-webkit-transition:;因为这个最简单好用,首先将图片都放在左侧,然后 ...

  2. python之对象回收机制

    python中,当程序执行完毕之后,python的垃圾回收机制就会将所有对象回收,清除占用的内存 请看如下代码 class Parent(): def __init__(self,name): sel ...

  3. AttributeError: 'list' object has no attribute 'sorted'

    效果图: 解决办法: 原因: AttributeError: 'list' object has no attribute 'sorted' 属性错误: list对象没有sorted属性方法. sor ...

  4. 与drawable的较量(一)

    前言 在android ui中drawable 是一个非常关键的要点,因为我们现在使用的花里胡哨的APP,都在胡里花哨的drawable 构建的. drawable,英文翻译为可拖拽的.说白了就是自己 ...

  5. APICloud打开三方地图整合

    一直想系统的整理打开地图的方法,今天抽时间把了百度,高德,腾讯,苹果自带地图都整理出来了,闲话不多说,直接上干货 ------------------------------------------- ...

  6. C++ 中的 unique 函数

    unique 函数是用来去除一个集合中重复元素的函数 若是在数组中,则调用此函数后,返回的除去重复元素的下一个指针的地方 若是在 vector中,则会返回重复元素下一个位置的迭代器,在调用erase函 ...

  7. Core 定时任务之HangFire

    ASP.NET Core 使用 Hangfire 很简单,首先,Nuget 安装程序包 > install-package Hangfire -pre 然后ConfigureServices添加 ...

  8. Redis 分布式锁的正确实现方式( Java 版 )

    前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...

  9. hadoop 基础

    common 一组分布式文件系统和通用I/O的组件与接口(序列化.java RPC和持久化数据结构) Avro 一种支持高效.跨语言的RPC以及永久存储数据的序列化系统 MapReduce 分布式数据 ...

  10. Django自定义状态码

    class BaseResponse: def __init__(self): self.code = 1000 self.data = None self.error = None @propert ...