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

在前面的三篇文章中介绍了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)

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

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

    原创作品,转载请注明出处:点我 上一篇文章Python高级编程之生成器(Generator)与coroutine(一):Generator中,我们介绍了什么是Generator,以及写了几个使用Gen ...

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

    转载请注明出处:点我 这是一系列的文章,会从基础开始一步步的介绍Python中的Generator以及coroutine(协程)(主要是介绍coroutine),并且详细的讲述了Python中coro ...

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

    原创作品,转载请注明出处:点我 在前两篇文章中,我们介绍了什么是Generator和coroutine,在这一篇文章中,我们会介绍coroutine在模拟pipeline(管道 )和控制Dataflo ...

  4. python高级编程技巧

    由python高级编程处学习 http://blog.sina.com.cn/s/blog_a89e19440101fb28.html Python列表解析语法[]和生成 器()语法类似 [expr  ...

  5. 第十一章:Python高级编程-协程和异步IO

    第十一章:Python高级编程-协程和异步IO Python3高级核心技术97讲 笔记 目录 第十一章:Python高级编程-协程和异步IO 11.1 并发.并行.同步.异步.阻塞.非阻塞 11.2 ...

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

    由于时间关系,python高级编程不在放在这边进行学习了,如果需要的朋友可以看下面的网盘进行下载 # # -*- coding: utf-8 -*- # # python:2.x # __author ...

  7. python高级编程之列表推导式

    1. 一个简单的例子 在Python中,如果我们想修改列表中所有元素的值,可以使用 for 循环语句来实现. 例如,将一个列表中的每个元素都替换为它的平方: >>> L = [1, ...

  8. python高级编程:有用的设计模式3

    # -*- coding: utf-8 -*-__author__ = 'Administrator'#python高级编程:有用的设计模式#访问者:有助于将算法从数据结构中分离出来"&qu ...

  9. python高级编程:有用的设计模式2

    # -*- coding: utf-8 -*- __author__ = 'Administrator' #python高级编程:有用的设计模式 #代理 """ 代理对一 ...

随机推荐

  1. 史上最全的iOS面试题及答案,且看且珍藏,错过就没有喽!

    1. Object-c的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好?为什么? 答:Object-c的类不可以多重继承;可以实现多个接口,通过实现多 ...

  2. Android WebDriver 浏览器自动测试工具介绍

    Selenium WebDriver 是浏览器自动测试工具,提供轻量级和优雅的方式来测试web应用.Selenium WebDriver作为Android SDK extra,支持Android 2. ...

  3. C 应用

    前言 1)操作符两端必须加空格,(每行第一个赋值语句对齐). 2)变量名必须是英文(不能是拼音):英文.数字.下划线和美元符号. 3)等于号 == 反过来写(0 == i%4)防止少些赋值号的错误. ...

  4. python 中 with 用法

    前言 with 语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源, 比如文件使用后自动关闭/线程中锁的自动获取和释放等. 问题引出 如下代码: fil ...

  5. 利用eChart绘制网页图表

    首先,最好的教程在这里:eCchart eChart所需JS: echarts.min.js china.js echarts.js 页面代码如下: 一.图表 <!DOCTYPE html> ...

  6. get_class 返回对象的类名

    get_class — 返回对象的类名 传一个对象,可以把这个对象的类名返回出来(字符串) 参考: http://php.net/manual/zh/function.get-class.php

  7. 将linux下的rm命令改造成mv到指定的目录下

    rm是Linux下文件删除的命令,它是Linux下非常强大却又非常危险的一条命令,特别是rm -rf有时候强大到让你欲哭无泪,当你想清除当前目录下的所有文件和目录时,很简单#rm -rf ./*这没什 ...

  8. 【iOS】自动引用计数 (循环引用)

    历史版本 ARC(Automatic Reference Counting,自动引用计数)极大地减少了Cocoa开发中的常见编程错误:retain跟release不匹配.ARC并不会消除对retain ...

  9. k8s-configmap

    一.目的 把应用的代码和配置分开,通过配置configmap管理pod,一种统一的集群配置管理方案.ConfigMap API资源提供了将配置数据注入容器的方式,同时保持容器是不知道Kubernete ...

  10. Java:Swing篇,实现JList、JTextArea的自动滚动,实时刷新功能

    1. 功能 作为swing的组件,JList与JTextArea是不可以单独实现滚动功能的,需要与JScrollPane结合才可以. 本代码中: JList实现从其它数据源获取数据,然后依次对这些数据 ...