• coroutine


      1 分享流畅的python一书, coroutine 章节中的出租车仿真的例子.
      2 
      3 from  collections import namedtuple
      4 import queue
      5 import random
      6 Event = namedtuple('Event', 'time process action')
      7 
      8 def taxi_simu(ident, trips, start_t =0 ):
      9     time = yield Event(start_t, ident, 'get out of garage')
     10     for i in range(trips):
     11         time = yield Event(time, ident, 'pick up passenger')
     12         time = yield Event(time, ident, 'passenger arrive destination')
     13 
     14     yield Event(time, ident, 'off duty, going home')
     15 
     16 
     17 class Emulator(object):
     18 
     19     def __init__(self, proc_mapping):
     20         self.events = queue.PriorityQueue()        #  保存排定事件的 PriorityQueue 对象,按时间正向排序。
     21         self.process = dict(proc_mapping)          #  获取的 procs_map 参数是一个字典(或其他映射),可是又从中构建一个字典,创建本地副本,
     22                                                    #  因为在仿真过程中,出租车回家后会从 self.procs 属性中移除,而我们不想修改用户传入的对象
     23     '''
     24     优先队列是离散事件仿真系统的基础构件:创建事件的顺序不定,放入这种队列之后,可以按照各个事件排定的时间顺序取出。
     25     '''
     26 
     27     def comupte_duration(self, previous_action):
     28         if 'get out of garage' in previous_action:
     29             return random.randint(1,3)
     30         elif 'pick up passenger' in previous_action:
     31             return random.randint(9,100)
     32         elif 'passenger arrive destination' in previous_action:
     33             return random.randint(5,10)
     34         else:
     35             return 8
     36     def run(self, end_time):
     37         for _, process in sorted(self.process.items()):    #  使用 sorted 函数获取 self.procs 中按键排序的元素;用不到键,因此赋值给 _。
     38             first_event = next(process)                    #  调用 next(proc) 预激各个协程,向前执行到第一个 yield 表达式,做好接收数据的准备。产出一个 Event 对象。
     39             self.events.put(first_event)                   #  把各个事件添加到 self.events 属性表示的 PriorityQueue 对象中。
     40 
     41         simu_time = 0                                      #  把 sim_time 变量(仿真钟)归零
     42         while simu_time < end_time:
     43             if self.events.empty():                        #  如果队列中没有未完成的事件,退出主循环
     44                 print('empty events queue, all events done')
     45                 break
     46 
     47             current_event = self.events.get()              #  获取优先队列中 time 属性最小的 Event 对象;这是当前事件(current_event)
     48             simu_time, process_id, previous_action = current_event       # 拆包 Event 对象中的数据。这一行代码会更新仿真钟 sim_time,对应于事件发生时的时间。
     49                                                                          # 这通常是离散事件仿真:每次循环时仿真钟不会以固定的量推进,而是根据各个事件持续的时间推进
     50             print('Taxi : ', process_id, process_id * ' ', current_event)   # 显示 Event 对象,指明是哪辆出租车,并根据出租车的编号缩进
     51             actived_process = self.process[process_id]                    # 从 self.procs 字典中获取表示当前活动的出租车的协程
     52             next_time = simu_time + self.comupte_duration(previous_action)
     53             try:
     54                 next_event = actived_process.send(next_time)      #  把计算得到的时间发给出租车协程。协程会产出下一个事件(next_event),或者抛出 StopIteration 异常(完成时)
     55             except StopIteration:
     56                 del self.process[process_id]                     # 如果抛出了 StopIteration 异常,从 self.procs 字典中删除那个协程
     57             else:
     58                 self.events.put(next_event)                      # 否则,把 next_event 放入队列中
     59         else:
     60             msg = '=== end of simulation time : {} events are pending ==='
     61             print(msg.format(self.events.qsize()))               #     如果循环由于仿真时间到了而退出,显示待完成的事件数量(有时可能碰巧是零, 如 endtime 足够大,就不有 event pending, 都会处理完)
     62 
     63 
     64 
     65 
     66 
     67 if __name__ == '__main__':
     68     taxi_num =5
     69     DEPARTURE_INTERVAL = 6
     70     end_time = 3333
     71     taxis = {i: taxi_simu(i, (i+1)*2, i*DEPARTURE_INTERVAL)
     72                     for i in range(taxi_num)}
     73 
     74     simu = Emulator(taxis)
     75     simu.run(end_time)
     76 
     77 
     78 '''
     79 OUTPUT,
     80 
     81     Taxi :  0  Event(time=0, process=0, action='get out of garage')
     82     Taxi :  0  Event(time=3, process=0, action='pick up passenger')
     83     Taxi :  1   Event(time=6, process=1, action='get out of garage')
     84     Taxi :  1   Event(time=7, process=1, action='pick up passenger')
     85     Taxi :  2    Event(time=12, process=2, action='get out of garage')
     86     Taxi :  2    Event(time=15, process=2, action='pick up passenger')
     87     Taxi :  3     Event(time=18, process=3, action='get out of garage')
     88     Taxi :  3     Event(time=21, process=3, action='pick up passenger')
     89     Taxi :  1   Event(time=22, process=1, action='passenger arrive destination')
     90     Taxi :  4      Event(time=24, process=4, action='get out of garage')
     91     Taxi :  1   Event(time=27, process=1, action='pick up passenger')
     92     Taxi :  4      Event(time=27, process=4, action='pick up passenger')
     93     Taxi :  3     Event(time=34, process=3, action='passenger arrive destination')
     94     Taxi :  3     Event(time=40, process=3, action='pick up passenger')
     95     Taxi :  0  Event(time=53, process=0, action='passenger arrive destination')
     96     Taxi :  0  Event(time=63, process=0, action='pick up passenger')
     97     Taxi :  3     Event(time=86, process=3, action='passenger arrive destination')
     98     Taxi :  1   Event(time=94, process=1, action='passenger arrive destination')
     99     Taxi :  2    Event(time=94, process=2, action='passenger arrive destination')
    100     Taxi :  3     Event(time=96, process=3, action='pick up passenger')
    101     Taxi :  2    Event(time=100, process=2, action='pick up passenger')
    102     Taxi :  1   Event(time=101, process=1, action='pick up passenger')
    103     Taxi :  4      Event(time=108, process=4, action='passenger arrive destination')
    104     Taxi :  4      Event(time=116, process=4, action='pick up passenger')
    105     Taxi :  3     Event(time=120, process=3, action='passenger arrive destination')
    106     Taxi :  3     Event(time=130, process=3, action='pick up passenger')
    107     Taxi :  0  Event(time=132, process=0, action='passenger arrive destination')
    108     Taxi :  4      Event(time=132, process=4, action='passenger arrive destination')
    109     Taxi :  0  Event(time=142, process=0, action='off duty, going home')
    110     Taxi :  4      Event(time=142, process=4, action='pick up passenger')
    111     Taxi :  3     Event(time=172, process=3, action='passenger arrive destination')
    112     Taxi :  3     Event(time=180, process=3, action='pick up passenger')
    113     Taxi :  2    Event(time=187, process=2, action='passenger arrive destination')
    114     Taxi :  1   Event(time=192, process=1, action='passenger arrive destination')
    115     Taxi :  4      Event(time=192, process=4, action='passenger arrive destination')
    116     Taxi :  1   Event(time=197, process=1, action='pick up passenger')
    117     Taxi :  2    Event(time=197, process=2, action='pick up passenger')
    118     Taxi :  4      Event(time=198, process=4, action='pick up passenger')
    119     Taxi :  3     Event(time=215, process=3, action='passenger arrive destination')
    120     Taxi :  3     Event(time=223, process=3, action='pick up passenger')
    121     Taxi :  1   Event(time=231, process=1, action='passenger arrive destination')
    122     Taxi :  4      Event(time=236, process=4, action='passenger arrive destination')
    123     Taxi :  1   Event(time=238, process=1, action='off duty, going home')
    124     Taxi :  4      Event(time=241, process=4, action='pick up passenger')
    125     Taxi :  2    Event(time=297, process=2, action='passenger arrive destination')
    126     Taxi :  2    Event(time=305, process=2, action='pick up passenger')
    127     Taxi :  3     Event(time=322, process=3, action='passenger arrive destination')
    128     Taxi :  3     Event(time=329, process=3, action='pick up passenger')
    129     Taxi :  4      Event(time=338, process=4, action='passenger arrive destination')
    130     Taxi :  4      Event(time=344, process=4, action='pick up passenger')
    131     Taxi :  2    Event(time=348, process=2, action='passenger arrive destination')
    132     Taxi :  2    Event(time=353, process=2, action='pick up passenger')
    133     Taxi :  3     Event(time=357, process=3, action='passenger arrive destination')
    134     Taxi :  3     Event(time=366, process=3, action='pick up passenger')
    135     Taxi :  4      Event(time=425, process=4, action='passenger arrive destination')
    136     Taxi :  4      Event(time=431, process=4, action='pick up passenger')
    137     Taxi :  3     Event(time=436, process=3, action='passenger arrive destination')
    138     Taxi :  3     Event(time=442, process=3, action='off duty, going home')
    139     Taxi :  2    Event(time=446, process=2, action='passenger arrive destination')
    140     Taxi :  2    Event(time=452, process=2, action='pick up passenger')
    141     Taxi :  4      Event(time=520, process=4, action='passenger arrive destination')
    142     Taxi :  2    Event(time=523, process=2, action='passenger arrive destination')
    143     Taxi :  4      Event(time=525, process=4, action='pick up passenger')
    144     Taxi :  2    Event(time=531, process=2, action='off duty, going home')
    145     Taxi :  4      Event(time=622, process=4, action='passenger arrive destination')
    146     Taxi :  4      Event(time=632, process=4, action='pick up passenger')
    147     Taxi :  4      Event(time=642, process=4, action='passenger arrive destination')
    148     Taxi :  4      Event(time=648, process=4, action='pick up passenger')
    149     Taxi :  4      Event(time=661, process=4, action='passenger arrive destination')
    150     Taxi :  4      Event(time=667, process=4, action='off duty, going home')
    151     empty events queue, all events done
    152 
    153 '''
  • 相关阅读:
    用 ArcMap 发布 ArcGIS Server FeatureServer Feature Access 服务 PostgreSQL 版本
    ArcMap 发布 ArcGIS Server OGC(WMSServer,MapServer)服务
    ArcScene 创建三维模型数据
    ArcMap 导入自定义样式Symbols
    ArcMap 导入 CGCS2000 线段数据
    ArcMap 导入 CGCS2000 点坐标数据
    ArcGis Server manager 忘记用户名和密码
    The view or its master was not found or no view engine supports the searched locations
    python小记(3)操作文件
    pytest(2) pytest与unittest的区别
  • 原文地址:https://www.cnblogs.com/zzyzz/p/7922308.html
Copyright © 2020-2023  润新知