chapter9_2 管道与过滤器
一个关于协同程序的经典示例就是“生产者-消费者”的问题。
一个不断产生值,一个不断消费这些值。比如:
function producer()
while true do
local x = io.read() --produce new value
send(x) --send it to consumer
end
end function consumer()
while true do
local x = receive() --receive value from producer
io.write(x,"\n") --consumer it
end
end
如何将send和receive匹配起来,这是一个典型的“谁有主循环”的问题。由于两则都有一个主循环,并且都将对方视为一个可调用的服务。
协同程序被称为一种匹配生产者和消费者的理想工具,一对resume-yield完全一改典型的调用者与被调用者之间的关系。
当一个协同程序调用yield时,它不是进入一个新的函数,而是从一个resume调用中返回。
同样对于resume,也不是启动一个新函数,而是从一次yield调用中返回。
两者都认为自己是主动方,对方是被动。
receive唤醒生产者,使它产生一个新值。而send则产生一个新值返还给消费者:
function receive()
local status,value = coroutine.resume(producer)
return value
end function send(x)
coroutine.yield(x)
end
因此,生产者现在一定是一个协同程序:
producer = coroutine.create( function ()
while true do
local x = io.read() --产生新值
send(x)
end
end)
在这种设计中,程序通过调用消费者来启动,当消费者需要一个新值时,唤醒生产者。
生产者返回一个新值后停止运行,并等待消费者的再次唤醒。这种设计称为“消费者驱动(consumer-driven)”。
还有一种就是使用“生产者驱动”设计,消费者是一个协同程序。
过滤器
过滤器是一种位于生产者和消费者之间的处理功能,可用于对数据的一些变换。
过滤器既是一个消费者又是一个生产者,它唤醒一个生产者促使其产生新值,又将变换后的值传递给消费者。
例如,在上面的代码中添加一个过滤器,在每行起始处插一个行号:
function receive(prod)
local status,value = coroutine.resume(prod)
return value
end function send(x)
coroutine.yield(x)
end function producer()
return coroutine.create(function ()
while true do
local x = io.read() --产生一个新值
send(x)
end
end)
end function filter(prod)
return coroutine.create(function ()
for line = ,math.huge do
local x = receive(prod) --获得一个新值
x = string.format("%5d %s",line,x)
send(x) -- send it to consumer
end
end)
end function consumer(prod)
while true do
local x = receive(prod) --获得一个新值
io.write(x,"\n") --消费一个新值
end
end
接下来运行代码,然后启动消费者:
p = producer ()
f = filter(p)
consumer(f) --或者更简单
consumer(filter(producer()))
在pipe中每个任务都在各自独立的进程中运行,而在协同程序中每项任务都在各自独立的协同程序中运行。
pipe在消费者与生产者之间提供一个缓冲器,因此它们的运行速度允许存在一定差异。但是,在pipe中进程间切换代价很高。
而在协同程序中,切换代价小得多(差不多等于函数调用)。
chapter9_2 管道与过滤器的更多相关文章
- 软件体系结构-分层、代理、MVC、管道与过滤器
什么是软件架构? 程序或计算系统的软件体系结构是系统的一个或多个结构,包括软件元素.这些元素的外部可见属性以及它们之间的关系. ——Software Engineering Institute(SEI ...
- [置顶] 学习鸟哥的Linux私房菜笔记(6)——过滤器、输入输出及管道
一.过滤器 Linux中的应用工具分为三种: 交互工具 过滤器 编辑器 能够接受数据,过滤再输出的工具,称之为过滤器 对过滤器和进程,存在着输入源与输出对象 二.输入.输出.重定向 输入:过滤器的数据 ...
- 学习鸟哥的Linux私房菜笔记(6)——过滤器、输入输出及管道
一.过滤器 Linux中的应用工具分为三种: 交互工具 过滤器 编辑器 能够接受数据,过滤再输出的工具,称之为过滤器 对过滤器和进程,存在着输入源与输出对象 二.输入.输出.重定向 输入:过滤器的数据 ...
- Asp.Net Core 轻松学-被低估的过滤器
前言 过滤器,从我们开始开发 Asp.Net 应用程序开始,就一直伴随在我们左右:Asp.Net Core 提供多种类型的过滤器,以满足多种多样的业务应用场景:并且在 Asp.Net Core ...
- 迷你MVVM框架 avalonjs 学习教程16、过滤器
avalon的过滤器是参考自angular与rivets.它也被称做管道文本过滤器,它的处理对象只能是文本(字符串),它只能用在文本绑定中,并且只能是双花括号形式.下面是各大家的过滤器比较: rive ...
- ngular6开发不完全笔记(二)-- 管道
自定义管道 管道(过滤器)为过滤数据显示下列list数据 pip.ts 文件 import { Pipe, PipeTransform } from '@angular/core'; import { ...
- asp.net 过滤器
asp.net 制作过滤器原理:重写ASP.net管道事件 1.通过HttpApplicationFactory创建一个HttpApplication对象,负责处理整个请求. 2.调用ProcessR ...
- angular管道操作符的使用
一.Angular的常用内置管道函数 比如说很多时候我们需要把数字显示成金额.大小写转换.日期小数转换等等. Angular管道对于象这样小型的转换来说是个很方便的选择. 管道是一个简单的函数,它接受 ...
- 理解ASP.NET Core - 过滤器(Filters)
注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博客或点击此处查看全文目录 Filter概览 如果你是从ASP.NET一路走过来的,那么你一定对过滤器(Filter)不陌 ...
随机推荐
- form -转载于blfshiye
Form API 表单API 文件夹 1.概述 2.亮点 3.使用方法 4.表单元素 4.1 基本表单元素 4.2 定制表单元素 5.经常使用函数 5.1 add_action_buttons($c ...
- hdu1030
#include<stdio.h>#include<math.h>void find(int n,int &l,int &r,int &level){ ...
- 《C++反汇编与逆向分析技术揭秘》——观察各种表达式的求值过程
---恢复内容开始--- 加法: 示例: 常量相加,则在编译期间就计算出两个常量相加后的结果,直接将这个结果参与运算,减少了运行期的计算.当有变量参与运算时,会先取出内存中的数据,放入通用寄存器中,再 ...
- 【4】学习JS 数据结构与算法笔记
第一章 JS 简介 1. 环境搭建的三种方式 1. 下载浏览器 2. 使用 Web 服务器 ( XAMPP ) 3. 使用 Node.js 搭建 Web 服务器 4. 代码地址>> 2. ...
- underScore学习1:匿名函数中call(this)的作用
匿名函数中(function(){}).call(this) 中的.call(this) 有什么用? 我们都知道,.call()可以改变函数执行时的context,即this的指向,源码中的.call ...
- python下载时报错 Errno 10060] A connection attempt failed because the connected party did not properly respond after a period of time
def downloadXml(isExists,filedir,filename): if not isExists: os.mkdir(filedir) local = os.path.join( ...
- CSS样式笔记
组合样式,CSS继承 .content { padding:0 0 0 5px; line-height: 30px; height: 30px; border: 1px solid #a6bee7; ...
- 理解iaas paas saas三种云服务区别
其实搞懂这个问题也不难,我们可以把云计算理解成一栋大楼,而这栋楼又可以分为顶楼.中间.低层三大块.那么我们就可以把Iass(基础设施).Pass(平台).Sass(软件)理解成这栋楼的三部分.基础设施 ...
- 【cocos2d-js 3.0】制作2048
2048:在一个4X4的方阵中,玩家需要滑动上面的数字,如果俩个数字相邻并且相等,则相加,需要达到2048,方可胜利. 因为在浏览器操作,所以此例的操作方法为:键盘上的w,s,a,d代表上下左右,也可 ...
- MFC 控件用法
1:IP Control 变量CIPAddressCtrl m_iAddr 关联DDX_Control(pDX,IDC_IPADDRESS1,m_iAddr); 设置地址:m_iAddr.SetAdd ...