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

在前面的三篇文章中介绍了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. HDUOJ-----X问题

    X问题 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis ...

  2. PowerDesigner 的常用方法

    http://www.cnblogs.com/studyzy/archive/2008/01/23/1050194.html PowerDesigner 的常用方法 修改外键命名规则 选择Databa ...

  3. RabbitMQ消息队列(四):分发到多Consumer(Publish/Subscribe)[转]

    上篇文章中,我们把每个Message都是deliver(提供)到某个Consumer.在这篇文章中,我们将会将同一个Message deliver(提供)到多个Consumer中.这个模式也被成为 & ...

  4. OGG_GoldenGate数据迁移三进程Extract / Dump / Relicat(案例)

    2014-03-04 Created By BaoXinjian

  5. AVL平衡二叉搜索树原理及各项操作编程实现

    C语言版 #include<stdio.h> #include "fatal.h" struct AvlNode; typedef struct AvlNode *Po ...

  6. MongoDB创建索引(不锁库方法)

    db.collection.createIndex( { a: 1 }, { background: true } )https://docs.mongodb.org/manual/tutorial/ ...

  7. Java:几个正则式应用(检查汉字、日期、EMAIL、手机号码的合法性,替换字符串等)

    1. 检查输入是否为合法汉字 /** * 判断输入字符是否为有效汉字 * @param str 字符 * @return 是否合法汉字 */ public static boolean isValid ...

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

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

  9. vim设置文本宽度

    'textwidth' 'tw'        number  (default 0)                        local to buffer                   ...

  10. 【Android】5.8 滑动条(SeekBar)

    分类:C#.Android.VS2015: 创建日期:2016-02-07 一.简介 滑动条也叫拖动条(用户可拖动改变滑动条的值),比如可让用户调节音量大小.调节屏幕亮度.调节歌曲或视频当前播放的位置 ...