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

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

代码如下,可看注释

 #-*-coding:utf-8 -*-
'''
用Python和coroutine实现一个简单的多任务系统
'''
# ##Step 1:Define Tasks###################################
import select
class Task(object):
taskid = 0 def __init__(self,target):
Task.taskid += 1
self.tid = Task.taskid # Task id
self.target = target # Target coroutine
self.sendval = None # Value to send def run(self):
return self.target.send(self.sendval)
# ############################################### # ##Step 2:The Scheduler#########################
import Queue
class Scheduler(object):
def __init__(self):
self.ready = Queue.Queue()
self.taskmap = {} # 正在等待的Tasks,key是taskid
self.exit_waiting = {} # 异步IO
# Holding areas for tasks blocking on I/O.These are
# dictionaries mapping file descriptions to tasks
# 键值为文件描述符
self.read_waiting = {}
self.write_waiting = {} def iotask(self):
while True:
if self.ready.empty():
# 如果ready为空,表示没有正在等待执行的队列
# timeout 为None,表示不关心任何文件描述符的变化
self.iopool(None)
else:
# ready不为空,则设置select函数不管文件描述符是否发生变化都立即返回
self.iopool(0)
yield def new(self,target):
newtask = Task(target)
self.taskmap[newtask.tid] = newtask
self.schedule(newtask)
return newtask.tid def schedule(self,task):
# 把task放到任务队列中去
self.ready.put(task) def exit(self,task):
print "Task %d terminated" %task.tid
del self.taskmap[task.tid]
# Notify other tasks waiting for exit
# 把正在等待的任务加入到正在执行的队列中去
for task in self.exit_waiting.pop(task.tid,[]):
self.schedule(task) def waitforexit(self,task,waittid):
'''
让一个任务等待另外一个任务,把这个任务加入到exit_waiting中去
返回True表示这个task正在等待队列中
'''
if waittid in self.taskmap:
self.exit_waiting.setdefault(waittid,[]).append(task)
return True
else:
return False def waitforread(self,task,fd):
'''
functions that simply put a task into to
one of the above dictionaries
'''
self.read_waiting[fd] = task def waitforwrite(self,task,fd):
self.write_waiting[fd] = task def iopool(self,timeout):
'''
I/O Polling.Use select() to determine which file
descriptors can be used.Unblock any associated task
'''
if self.read_waiting or self.write_waiting:
# 获取I/O事件,一旦获取到,就放入到执行队列中取,等待执行
r,w,e = select.select(self.read_waiting,
self.write_waiting,[],timeout)
for fd in r:
self.schedule(self.read_waiting.pop(fd)) for fd in w:
self.schedule(self.write_waiting.pop(fd)) def mainloop(self):
self.new(self.iotask()) # Launch I/O polls
while self.taskmap:
task = self.ready.get()
try:
result = task.run()
# 如果task执行的是System call,则对当前环境进行保存
# 然后在执行System Call
if isinstance(result,SystemCall):
# 把当前的环境保存,即保存当前运行的task和sched
result.task = task
result.sched = self
result.handle()
continue
except StopIteration:
self.exit(task)
# print("task is over")
continue
self.schedule(task)
# ##Step 2:The Scheduler######################### # ##SystemCall#########################
class SystemCall(object):
'''
所有系统调用的基类,继承自该类的类要重写handle函数
'''
def handle(self):
pass class GetTid(SystemCall):
'''
获取任务ID
'''
def handle(self):
self.task.sendval = self.task.tid
self.sched.schedule(self.task) class NewTask(SystemCall):
'''
新建一个Task
'''
def __init__(self,target):
self.target = target def handle(self):
# 在这里把target封装成Task
# 是在这里把新生成的task加入到执行队列当中去
tid = self.sched.new(self.target)
self.task.sendval = tid
# 把执行这个系统调用的父task重新加入到执行队列中去
# 这一点很关键,因为判断一个task是否结束是通过taskmap的
# 这个task只是暂时被挂起,要重新放到queue中去
self.sched.schedule(self.task) class KillTask(SystemCall):
'''
杀死一个Task
'''
def __init__(self,tid):
self.tid = tid def handle(self):
task = self.sched.taskmap.get(self.tid,None)
# task指的是要被kill掉的那个task
# self.task指的是发起KillTask这个系统调用task
if task:
task.target.close()
self.task.sendval = None
else:
self.task.sendval = False
# target.close()只是产生一个StopIteration异常
self.sched.schedule(self.task) class WaitTask(SystemCall):
'''
让任务进行等待 系统调用
'''
def __init__(self,tid):
self.tid = tid def handle(self):
result = self.sched.waitforexit(self.task,self.tid)
self.task.sendval = result
# 如果等待的是一个不存在的task,则立即返回
if not result:
self.sched.schedule(self.task) class ReadWait(SystemCall):
'''
异步读 系统调用
'''
def __init__(self,f):
self.f = f def handle(self):
fd = self.f.fileno()
self.sched.waitforread(self.task,fd) class WriteWait(SystemCall):
'''
异步写 系统调用
'''
def _init__(self,f):
self.f = f def handle(self):
fd = self.f.fileno()
self.sched.waitforwrite(self.task,fd)

最新文章

  1. linux 批量删除进程
  2. 知道创宇研发技能表v3.1
  3. pyvcf 模块
  4. 2.html5的基本格式
  5. coco2d-js 多屏适配相关API
  6. careercup-递归和动态规划 9.10
  7. 【性能测试】【Jmeter】学习(1)
  8. 秒味课堂Angular js笔记------Angular js中的工具方法
  9. 仿桌面通知pnotify插件
  10. Android自己定义组件系列【9】——Canvas绘制折线图
  11. 让MyEclipse里的Tomcat自动reloadable
  12. CodeForces 614C Peter and Snow Blower
  13. 【高并发简单解决方案】redis队列缓存 + mysql 批量入库 + php离线整合
  14. window mysql安装
  15. zepto和jQuery on事件委托在苹果手机上的”坑“
  16. windows程序设计 获取系统文件路径
  17. 一个简单SpringBoot例子
  18. 纯MarkDown博客阅读体验优化
  19. C++11--正则表达式<regex>
  20. environment variable is too large 2047

热门文章

  1. android 自定义ViewSwipeBackHelper,实现左滑结束Activity
  2. setContentView(R.layout.activity_main)无法正常引用
  3. java实现简单webserver(分析+源码)
  4. 文字识别:CRNN
  5. session和cookie的联系
  6. BZOJ 1029 JSOI2007 建筑抢修 贪心+堆
  7. vim+cscope简易教程
  8. PHP二维数组如何根据某个字段排序
  9. 批处理学习笔记14 - 把所有.mp4文件全部拷贝进统一目录
  10. GIS(一)——在js版搜索地图上加入Marker标记