分享流畅的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. 干货!直击JVM底层 —— Java Class字节码文件解析

    目录 前言 如何阅读class文件 基本概念 无符号数&表 常量池 魔数(magic number) & 版本号 常量池 访问标志 类引索&父类引索&接口引索集合 字段 ...

  2. CVE-2019-0708远程桌面服务远程执行代码漏洞exp利用过程

    CVE-2019-0708远程桌面服务远程执行代码漏洞 上边这洞是啥我就不多说了,描述类的自行百度. 受影响系统版本范围: Windows Server 2008 R2 Windows Server ...

  3. Js字符串按数量分组

    代码: function group(ss,step) { var r = []; function doGroup(s) { if (!s) return; r.push(s.substr(0, s ...

  4. MySQL UTF-8 常用字符排序规则

    排序规则 解释 utf8_general_ci 不区分大小写 utf8_general_cs 区分大小写 utf8_bin 区分大小写,字符串每个字符串用二进制数据编译存储,且支持存储二进制数据

  5. .NET使用FastDBF写入DBF

    FastDBF源代码地址:https://github.com/SocialExplorer/FastDBF 第一步在解决方案中新建一个类库的项目:取名为SocialExplorer.FastDBF ...

  6. 树上点分治 poj 1741

    Give a tree with n vertices,each edge has a length(positive integer less than 1001). Define dist(u,v ...

  7. ubuntu系统搭建(jdk1.8+mysql5.7.28+Hadoop2.7.7+hive3.1.2)

    一不小心电脑没电关机之后虚拟机就挂了,然后下定决心重新搭一个虚拟机. 以下是几天安装过程的记录以及一些小提示,包括在ubuntu中安装jdk1.8+mysql5.7.28+Hadoop2.7.7+hi ...

  8. Nginx模块讲解

    Nginx模块分为:nginx官方模块.第三方模块 通过nginx -V查看编译参数,可以看到官方编译的模块 --with-compat --with-file-aio --with-threads ...

  9. stormzhangB站直播之总结

    此文转自个人微信公众号,原链接为:https://mp.weixin.qq.com/s?__biz=MzUxODk0ODQ3Ng==&mid=2247484313&idx=1& ...

  10. kaggle预测房价的代码步骤

    # -*- coding: utf-8 -*- """ Created on Sat Oct 20 14:03:05 2018 @author: 12958 " ...