• 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 '''
  • 相关阅读:
    C字符串和C++字符串
    Linux的用户态和内核态
    知乎问答:如何理解“In UNIX, everything is a file”?
    科普:并行计算、分布式计算、集群计算和云计算
    个人使用VIM的一些总结
    C语言回调函数学习
    Python的函数参数传递:传值?引用?
    ECMAScript 函数函数概述
    ECMAScript 函数arguments 对象
    ECMAScript 语句with 语句
  • 原文地址:https://www.cnblogs.com/zzyzz/p/7922308.html
Copyright © 2020-2023  润新知