分享流畅的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. 小白学 Python 爬虫(41):爬虫框架 Scrapy 入门基础(八)对接 Splash 实战

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  2. windows I/O设备

    当外部设备连接到windows后,设备所连接到的集线器驱动程序将为设备分配硬件ID,然后Windows 使用硬件 Id 查找设备与包含设备驱动程序的驱动程序包之间最近的匹配项. 如果查找到,设备就可以 ...

  3. cogs 1298. 通讯问题 Tarjan

    1298. 通讯问题 ★★   输入文件:jdltt.in   输出文件:jdltt.out   简单对比时间限制:1 s   内存限制:128 MB [题目描述] 一个篮球队有n个篮球队员,每个队员 ...

  4. IDEA不编译空文件夹

    今天做项目的时候发现idea编译工程不会编译空文件夹,在resources下新建了个存储文件的空文件夹,编译后target里竟然没有,一直报空指针. 随便丢一个文件进去就行了,放一个demo.txt的 ...

  5. 切蛋糕(贪心 or 优先队列)

    链接:https://www.nowcoder.com/acm/contest/80/D来源:牛客网 最可爱的applese生日啦,他准备了许多个质量不同的蛋糕,想请一些同学来参加他的派对为他庆生,为 ...

  6. 前端笔记6-js2

    1.break 和continue用法 break结束本次循环,如果想结束外层循环,可以通过这个label来指定要结束的循环. continue可以用来跳过当次循环,如果想跳过外次循环,也可以通过这个 ...

  7. background-position和position

    1.background-position:表示背景定位的属性.描述属性值时,有两种方式:一是像素描述:而是单位描述. (1)像素描述: 格式如下: background-position:向右偏移量 ...

  8. 18个Java8日期处理的实践,对于程序员太有用了!

    18个Java8日期处理的实践,对于程序员太有用了! Java 8 推出了全新的日期时间API,在教程中我们将通过一些简单的实例来学习如何使用新API. Java处理日期.日历和时间的方式一直为社区所 ...

  9. 关于neo4j初入门(4)

    关于admin管理员 数据库备份和恢复 Neo4j数据库备份 步骤1 -点击“Neo4j Community”,如下图所示 Windows“开始”按钮>> "All Progra ...

  10. 图解 Kubernetes

    容器 在了解 Kubernetes 之前,让我们先了解一个容器. 因为如果不了解容器就没法聊容器编排. 容器就是...一个你塞入所有材料的容器. "材料"是指你的应用代码.依赖库, ...