Python高级编程之生成器(Generator)与coroutine(四):一个简单的多任务系统

啊,终于要把这一个系列写完整了,好高兴啊

在前面的三篇文章中介绍了Python的Python的Generator和coroutine(协程)相关的编程技术,接下来这篇文章会用Python的coroutine技术实现一个简单的多任务的操作系统

代码如下,可看注释

  1 #-*-coding:utf-8 -*-
  2 ‘‘‘
  3 用Python和coroutine实现一个简单的多任务系统
  4 ‘‘‘
  5 # ##Step 1:Define Tasks###################################
  6 import select
  7 class Task(object):
  8     taskid = 0
  9
 10     def __init__(self,target):
 11         Task.taskid += 1
 12         self.tid = Task.taskid    # Task id
 13         self.target = target      # Target coroutine
 14         self.sendval = None       # Value to send
 15
 16     def run(self):
 17         return self.target.send(self.sendval)
 18 # ###############################################
 19
 20 # ##Step 2:The Scheduler#########################
 21 import Queue
 22 class Scheduler(object):
 23     def __init__(self):
 24         self.ready = Queue.Queue()
 25         self.taskmap = {}
 26
 27         # 正在等待的Tasks,key是taskid
 28         self.exit_waiting = {}
 29
 30         # 异步IO
 31         # Holding areas for tasks blocking on I/O.These are
 32         # dictionaries mapping file descriptions to tasks
 33         # 键值为文件描述符
 34         self.read_waiting = {}
 35         self.write_waiting = {}
 36
 37
 38     def iotask(self):
 39         while True:
 40             if self.ready.empty():
 41                 # 如果ready为空,表示没有正在等待执行的队列
 42                 # timeout 为None,表示不关心任何文件描述符的变化
 43                 self.iopool(None)
 44             else:
 45                 # ready不为空,则设置select函数不管文件描述符是否发生变化都立即返回
 46                 self.iopool(0)
 47             yield
 48
 49
 50     def new(self,target):
 51         newtask = Task(target)
 52         self.taskmap[newtask.tid] = newtask
 53         self.schedule(newtask)
 54         return newtask.tid
 55
 56     def schedule(self,task):
 57         # 把task放到任务队列中去
 58         self.ready.put(task)
 59
 60     def exit(self,task):
 61         print "Task %d terminated" %task.tid
 62         del self.taskmap[task.tid]
 63         # Notify other tasks waiting for exit
 64         # 把正在等待的任务加入到正在执行的队列中去
 65         for task in self.exit_waiting.pop(task.tid,[]):
 66             self.schedule(task)
 67
 68     def waitforexit(self,task,waittid):
 69         ‘‘‘
 70         让一个任务等待另外一个任务,把这个任务加入到exit_waiting中去
 71         返回True表示这个task正在等待队列中
 72         ‘‘‘
 73         if waittid in self.taskmap:
 74             self.exit_waiting.setdefault(waittid,[]).append(task)
 75             return True
 76         else:
 77             return False
 78
 79
 80     def waitforread(self,task,fd):
 81         ‘‘‘
 82         functions that simply put a task into to
 83         one of the above dictionaries
 84         ‘‘‘
 85         self.read_waiting[fd] = task
 86
 87     def waitforwrite(self,task,fd):
 88         self.write_waiting[fd] = task
 89
 90     def iopool(self,timeout):
 91         ‘‘‘
 92         I/O Polling.Use select() to determine which file
 93         descriptors can be used.Unblock any associated task
 94         ‘‘‘
 95         if self.read_waiting or self.write_waiting:
 96             # 获取I/O事件,一旦获取到,就放入到执行队列中取,等待执行
 97             r,w,e = select.select(self.read_waiting,
 98                                   self.write_waiting,[],timeout)
 99             for fd in r:
100                 self.schedule(self.read_waiting.pop(fd))
101
102             for fd in w:
103                 self.schedule(self.write_waiting.pop(fd))
104
105     def mainloop(self):
106         self.new(self.iotask())  # Launch I/O polls
107         while self.taskmap:
108             task = self.ready.get()
109             try:
110                 result = task.run()
111                 # 如果task执行的是System call,则对当前环境进行保存
112                 # 然后在执行System Call
113                 if isinstance(result,SystemCall):
114                     # 把当前的环境保存,即保存当前运行的task和sched
115                     result.task = task
116                     result.sched = self
117                     result.handle()
118                     continue
119             except StopIteration:
120                 self.exit(task)
121                 # print("task is over")
122                 continue
123             self.schedule(task)
124 # ##Step 2:The Scheduler#########################
125
126
127 # ##SystemCall#########################
128 class SystemCall(object):
129     ‘‘‘
130     所有系统调用的基类,继承自该类的类要重写handle函数
131     ‘‘‘
132     def handle(self):
133         pass
134
135
136 class GetTid(SystemCall):
137     ‘‘‘
138     获取任务ID
139     ‘‘‘
140     def handle(self):
141         self.task.sendval = self.task.tid
142         self.sched.schedule(self.task)
143
144
145 class NewTask(SystemCall):
146     ‘‘‘
147     新建一个Task
148     ‘‘‘
149     def __init__(self,target):
150         self.target = target
151
152     def handle(self):
153         # 在这里把target封装成Task
154         # 是在这里把新生成的task加入到执行队列当中去
155         tid = self.sched.new(self.target)
156         self.task.sendval = tid
157         # 把执行这个系统调用的父task重新加入到执行队列中去
158         # 这一点很关键,因为判断一个task是否结束是通过taskmap的
159         # 这个task只是暂时被挂起,要重新放到queue中去
160         self.sched.schedule(self.task)
161
162 class KillTask(SystemCall):
163     ‘‘‘
164     杀死一个Task
165     ‘‘‘
166     def __init__(self,tid):
167         self.tid = tid
168
169     def handle(self):
170         task = self.sched.taskmap.get(self.tid,None)
171         # task指的是要被kill掉的那个task
172         # self.task指的是发起KillTask这个系统调用task
173         if task:
174             task.target.close()
175             self.task.sendval = None
176         else:
177             self.task.sendval = False
178         # target.close()只是产生一个StopIteration异常
179         self.sched.schedule(self.task)
180
181
182 class WaitTask(SystemCall):
183     ‘‘‘
184     让任务进行等待 系统调用
185     ‘‘‘
186     def __init__(self,tid):
187         self.tid = tid
188
189     def handle(self):
190         result = self.sched.waitforexit(self.task,self.tid)
191         self.task.sendval = result
192         # 如果等待的是一个不存在的task,则立即返回
193         if not  result:
194             self.sched.schedule(self.task)
195
196
197
198
199 class ReadWait(SystemCall):
200     ‘‘‘
201     异步读 系统调用
202     ‘‘‘
203     def __init__(self,f):
204         self.f = f
205
206     def handle(self):
207         fd = self.f.fileno()
208         self.sched.waitforread(self.task,fd)
209
210 class WriteWait(SystemCall):
211     ‘‘‘
212     异步写 系统调用
213     ‘‘‘
214     def _init__(self,f):
215         self.f = f
216
217     def handle(self):
218         fd = self.f.fileno()
219         self.sched.waitforwrite(self.task,fd)
时间: 2024-10-25 00:28:56

Python高级编程之生成器(Generator)与coroutine(四):一个简单的多任务系统的相关文章

Python高级编程之生成器(Generator)与coroutine(二):coroutine介绍

原创作品,转载请注明出处:点我 上一篇文章Python高级编程之生成器(Generator)与coroutine(一):Generator中,我们介绍了什么是Generator,以及写了几个使用Generator Function的示例,这一小节,我们会介绍Python的coroutine,以及会有一个小例子,再接下来的文章中会以代码的形式一步步介绍coroutine的高级用法. coroutine(协程) 什么是coroutine?coroutine跟Generator有什么区别?下面先看一段

Python高级编程之生成器(Generator)与coroutine(一):Generator

这是一系列的文章,会从基础开始一步步的介绍Python中的Generator以及coroutine(协程)(主要是介绍coroutine),并且详细的讲述了Python中coroutine的各种高级用法,最后会用coroutine实现一个简单的多任务的操作系统. 其实也是看完这篇文章的学习笔记吧!O(∩_∩)O 生成器(Generator) 什么是生成器?在Python中,生成器(Generator)是一个带有yield关键字的函数 1 def gene(): 2 a = 1 3 print "

Python高级编程之生成器(Generator)与coroutine(二):coroutine与pipeline(管道)和Dataflow(数据流_

原创作品,转载请注明出处:点我 在前两篇文章中,我们介绍了什么是Generator和coroutine,在这一篇文章中,我们会介绍coroutine在模拟pipeline(管道 )和控制Dataflow(数据流)方面的运用. coroutine可以用来模拟pipeline行为.通过把多个coroutine串联在一起来实现pipe,在这个管道中,数据是通过send()函数在各个coroutine之间传递的: 但是这些在pipe中传递的数据哪里来的呢?这就需要一个数据源,或者说producer.这个

python高级编程之生成器表达式和itertools模块

# -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' #生成器表达式和itertools模块 #yield 中可以使用圆括号代替中括号 iter0=(x**2 for x  in range(10)if x%2==0) for iter1 in iter0: print iter1 #结果 """ 0 4 16 36 64 """ #这样的表达式被称为生成器或者gene

python高级编程-Part1 生成器和迭代器

迭代器和生成器是python学者们经常谈到的话题,我也不能免俗,因为实在值得总结一下.     迭代器 迭代器是对可迭代对象进行操作,通过next方法一次吐出一个元素的工具.我们用到的for..in..内部使用的就是迭代器功能. 如果要自定义一个迭代器类的话,需要满足下面的条件: 需要在类中定义__iter__方法返回self自身,表示这是一个迭代器: 需要定义next方法来返回迭代的值,其中应该包含StopIteration异常的判断 下面试着写一个自定义迭代器类的例子(模仿自Python高级

python高级编程之迭代器与生成器

# -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' #迭代器与生成器 #--------------------------------------- #迭代器基于2个方法 """ next:返回容器下一个项目 __iter__:返回迭代器本身 """ #通过内建函数和序列来创建 i=iter('abc') print i.next()#a print i.next(

python高级编程之装饰器04

from __future__ import with_statement # -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' #with和contextlib #对于要确保即使发生一个错误时也能运行一些清理代码而言,try...finally语句很有用,对以下场景,如: """ 关闭一个文件, 释放一个锁 创建一个临时代码补丁 在特殊环境中运行受保护代码 ----------- with语句覆盖

python高级编程之选择好名称:完

由于时间关系,python高级编程不在放在这边进行学习了,如果需要的朋友可以看下面的网盘进行下载 # # -*- coding: utf-8 -*- # # python:2.x # __author__ = 'Administrator' #使用API #跟踪冗长 #创建代码库时,最常见的错误是api冗长(api verbosity),当一个功能对包的调用是一组而不是一个时,出现下面错误 #script_engine包例子 #from script_engine import make_con

Python高级编程pdf

下载地址:网盘下载 内容简介  · · · · · · <Python高级编程>通过大量的实例,介绍了Python语言的最佳实践和敏捷开发方法,并涉及整个软件生命周期的高级主题,诸如持续集成.版本控制系统.包的发行和分发.开发模式.文档编写等.<Python高级编程>首先介绍如何设置最优的开发环境,然后以Python敏捷开发方法为线索,阐述如何将已被验证的面向对象原则应用到设计中.这些内容为开发人员和项目管理人员提供了整个软件工程中的许多高级概念以及专家级的建议,其中有些内容的意义