前面给了个Io异步编程的例子,最后说“和Erlang比一比“,我指的是Erlang做类似的功能需要pmap。
为什么Io的List#map可以适应这种并行调用?本文简单分析一下。
通过阅读源码,首先可以确定的是map本身没有作任何特殊处理,所以重点放在"@"这个操作符上,它完成异步操作。
经过测试发现,方法如果是异步调用(应该说消息是异步发送,说方法调用感觉自然一些),如果不“使用”调用结果,是不会等待结果返回的。这里的“使用”并不是简单地赋给一个变量,而是真正使用这个变量,比如返回一个整数,简单地:
a := foo @bar
并不会等待调用的结果,只有使用a这个变量时--例如b := a+1, a println--它才会等待调用结果。
前面的并行map正是使用了这个特性,你可以觉得奇怪,结果放到一个list里面难道不算是使用吗?其实不然,它放入的是一个Proxy对象,并非真正的结果,只有你取用list成员时,它才会取结果。有一点细节是,就算你不取结果,但调用也是真的发生了,只是这边不用等待。
它是如何完成这个过程的?简单看一下Actor.io这个文件,"@"的实现就在这里:
Object do(
setSlot("@", method(
//writeln("@ ", call argAt(0))
m := call argAt(0) asMessageWithEvaluatedArgs(call sender)
f := Future clone setRunTarget(self) setRunMessage(m)
self actorRun
self actorQueue append(f)
f futureProxy
))
)
可以看出它把调用塞到队列里,然后返回一个Proxy对象,所以我们的list里实际上都是FutureProxy对象,把结果类型打印一下就知道了:
result at(0) type println
但为什么result println打印的是包含几个整数的list?
原因在于FutureProxy:
FutureProxy := Object clone do(
with := method(future,
p := self clone
p _future := future
p forward := self getSlot("_forward")
p _become := self getSlot("become")
//p xyz := method(_future writeln("XYZ!"))
p type := "FutureProxy"
p removeAllProtos
p
)
_forward := method(
//_future writeln("FutureProxy forward ", call message)
_future waitOnResult
self doMessage(call message, call sender)
)
)
它定义了forward方法,这个方法和Ruby的method_missing相似,由于它没有其它方法,所以使用它(给它发消息)时都会自然调用到这个方法。它在这里完成的功能是等待结果,然后取得结果。这个功能也可以用Ruby来完成,Io这一整套东西其实可以用Ruby 1.9来完成,很可能比现在的Io效率高很多。
分享到:
相关推荐
解决删除目录提示:System.IO.IOException: 目录不是空的
java.io.CharConversionException: isHexDigit.最近项目运行出现了这个问题,刚开始就知道是编码问题,怎么改编码都不正确,在网上搜到的文章。
System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.ReportViewer.WinForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies....
Android Studio上运行Flutter,报错could not find io.flutter:flutter_embedding_debug的错误,需要替换以上zip文件即可,Android Studio 4.2.0, Flutter 2.2.3, Dart 2.13.4
Visution Mapio Pro(3D全景制作软件)是一个用于创建投影显示的Mapio显像技术软件。 现在,你不仅可以与标准屏幕工作,也与任何倾斜,包括圆柱形和球形及各种形状。 无限制片可以让你分开的视频覆盖的任何空间。 您...
map集合的特性和它的遍历方式 还有一个根据Set特性的一个排序 以及IO流 字节流和字符流实现代码
YRC1000 并行IO使用说明书,安川机器人信号分类,专用信号解释说明,并行io指令实例演示,标准梯形图模型等。
安川Motoman机械手的并行IO指令使用说明手册
内部自动缓存buffer,友好的关闭流closeQuetly,以LineIterator行迭代器的形式读取文件,流
最新单片机仿真 IO并行口直接驱动单个数码管最新单片机仿真 IO并行口直接驱动单个数码管最新单片机仿真 IO并行口直接驱动单个数码管最新单片机仿真 IO并行口直接驱动单个数码管最新单片机仿真 IO并行口直接驱动单个...
Oracle10G控制台解决办法-Io 异常:Unknown host specified解决方法
socket.io-dart:socket.io-dart:socket.io的Dartlang端口https:github.comsocketiosocket.io
并行IO说明
文章目录华为云讲解:Istio架构与原理Service MeshKubernetesIstio 架构基础Istio 基本概念Istio & Kubernetes :架构结合运行一个Istio集群 Service Mesh Kubernetes Kubernetes 提供云平台基础设施层强大容器编排...
网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO
PlatformIO项目示例:开发平台嵌入式的 技嘉GD32V 英飞凌XMC 英特尔ARC32 英特尔MCS-51(8051) 肯德利K210 莱迪思iCE40 美心32 单片机PIC32 北欧nRF51 北欧nRF52 细胞核恩智浦i.MX RT 恩智浦LPC OpenHW集团树莓派RP...
解决docker报错dial tcp lookup registry-1.docker.io
fileupload组件依赖的commons-io组件
- configMap - secret - emptyDir - hostPath allowedHostPaths: - pathPrefix: "/etc/cni/net.d" - pathPrefix: "/etc/kube-flannel" - pathPrefix: "/run/flannel" readOnlyRootFilesystem: ...
drawio-webdav采用webdav方式存储drawio文件的解决方案目前实现存储到minio待实现存储到dzzoffice存储到nextcloudTODO 增加内网部署 draw.ioDEMO使用dockerdocker run --rm -p 3000:3000 itrizon/drawio-webdav:demo...