锯齿型眼志配对:使用future实现内置异步API
来源:百度文库 编辑:九乡新闻网 时间:2024/04/27 21:59:17
当设计并发策略时,要将 "what做什么"和 "how怎么做"进行分离,
Prefer Futures to Baked-In "Async APIs"一文介绍了如何使用语言的并行API通过异步来实现这点。
普通同步性质的方法如下:
RetType DoSomething(
InParameters ins,
OutParameters outs
);
如果DoSomething 将花费很长时间执行,无论它是否耗费CPU,比如从数据库中加载一个数据就是很耗费时间的,那么是不是在DoSomething执行的同时,我们做做其他事情呢?
比如:
result = DoSomething( this, that, outTheOther );
OtherWork();
如果OtherWork不依赖result 这个值,那么我们让DoSomething使用通常意义上的异步执行就没有问题。
但是如果OtherWork依赖上一步执行结果result,怎么办?
第一个方案是使用Begin/End 模式实现:
设计一个开始接口,如下
IAsyncResult BeginDoSomething(
InParameters ins
);
再设计一个结果接口,如下:
RetType EndDoSomething(
IAsyncResult asyncResult,//上一接口计算的结果
OutParameters outs
);
使用方式如下代码:
IAsyncResult ar = BeginDoSomething( this, that );
result = DoSomething( this, that, outTheOther );
//在DoSomething运行同时,执行OtherWork
OtherWork();
//将上面两个融合Join,
ar.AsyncWaitHandle.WaitOne();//必要时需要等待
result = EndDoSomething( ar, outtheOther );
这个模式需要在最后等待,无论DoSomething和OtherWork哪个先做完,都要等待对方,这个性能会很差,当然该文从.NET框架等多个角度说明这个模式一些局限,这里不再引述,可以参考原文。
我们主要目的是要将“如何异步运行这个工作 ”(也就是调用"how如何做")和做什么分离开来。在上面这个案例中,我们关注的是让DoSomething和OtherWork异步启动,而DoSomething如何异步运行(how),应该不是我们关心的,至少应该从上面这段调用代码中分离出去。而 begin/end 模式并没有帮助我们做到这点,相反是将How和What耦合在一起了。
让我们来看看如何实现How和What分离解耦:
1.使用一个分离的Task任务调用来运行How的工作内容,根据你的语言平台,比如如果是Java/.NET,使用pool.run( /*task*/ ),如果C++0x,使用async( /*task*/ ) .
2.使用futures来管理异步运行的结果. 这实际就是类Java JDK中的Future API, C++0x标准即将也会有,而.NET下一个版本使用的是Task.
这样,上面案例代码如下:
//第一步 asynchronous call
future<int> result =
async( ()=<{ return CallSomeFunc(x,y,z); } );
//第二步 code here runs concurrently with CallSomeFunc
//同时运行其他事情
//第三步 use result when it's ready (this might block)
//在这里使用异步运行dosomething的结果
DoSomethingWith( result.value() );
这里代码为什么和前面代码不完全一致,因为我们根据How和What分离,更改了设计,如果前面案例的otherwork依赖DoSomething的结果,那么,我们就要将otherwork内容进行分解,将otherwork中不依赖DoSomething结果的内容首先运行,也就是上面第二步,然后,使用在第三步,我们将两个计算结果融合。
这种使用Future特性将How和What分离的模式,已经被使用在Jdonframework 6.2的Domain Events,实际就是Domain Events的内在机制,当领域模型中激活一个事件时,实际就是发送了一个消息,在Jdonframework中,监听消息实际执行如下代码:
private void asynExecMessageListener(final DomainMessage message) {
FutureTask futureTask = new FutureTask(new Callable() {
public Boolean call() throws Exception {
try {
message.getMessageListener().action(message);
} catch (Exception e) {
....
return true;
}
});
message.addFutureTask(futureTask);//运行futuretask
executor.execute(futureTask);//相当于pool.run
}
应该说:JdonFramework 6.2是将EDA和Java并行计算,异步可伸缩性融合在一起,在设计理念是先进的,本文也可以验证这点。参考Domain Events异步应用
[该贴被admin于2010-01-20 09:22修改过]
RetType DoSomething(
InParameters ins,
OutParameters outs
);
result = DoSomething( this, that, outTheOther );
OtherWork();
IAsyncResult BeginDoSomething(
InParameters ins
);
RetType EndDoSomething(
IAsyncResult asyncResult,//上一接口计算的结果
OutParameters outs
);
IAsyncResult ar = BeginDoSomething( this, that );
result = DoSomething( this, that, outTheOther );
//在DoSomething运行同时,执行OtherWork
OtherWork();
//将上面两个融合Join,
ar.AsyncWaitHandle.WaitOne();//必要时需要等待
result = EndDoSomething( ar, outtheOther );
这样,上面案例代码如下:
//第一步 asynchronous call
future<int> result =
async( ()=<{ return CallSomeFunc(x,y,z); } );
//第二步 code here runs concurrently with CallSomeFunc
//同时运行其他事情
//第三步 use result when it's ready (this might block)
//在这里使用异步运行dosomething的结果
DoSomethingWith( result.value() );
这里代码为什么和前面代码不完全一致,因为我们根据How和What分离,更改了设计,如果前面案例的otherwork依赖DoSomething的结果,那么,我们就要将otherwork内容进行分解,将otherwork中不依赖DoSomething结果的内容首先运行,也就是上面第二步,然后,使用在第三步,我们将两个计算结果融合。
这种使用Future特性将How和What分离的模式,已经被使用在Jdonframework 6.2的Domain Events,实际就是Domain Events的内在机制,当领域模型中激活一个事件时,实际就是发送了一个消息,在Jdonframework中,监听消息实际执行如下代码:
private void asynExecMessageListener(final DomainMessage message) {
FutureTask futureTask = new FutureTask(new Callable() {
public Boolean call() throws Exception {
try {
message.getMessageListener().action(message);
} catch (Exception e) {
....
return true;
}
});
message.addFutureTask(futureTask);//运行futuretask
executor.execute(futureTask);//相当于pool.run
}
应该说:JdonFramework 6.2是将EDA和Java并行计算,异步可伸缩性融合在一起,在设计理念是先进的,本文也可以验证这点。参考Domain Events异步应用
[该贴被admin于2010-01-20 09:22修改过]
xmuzyu
通过切分,使得数据分布在多个节点,然后进行并行处理,而处理的方式采用移动计算到存储数据的地方,其实这里面也涉及到了how,what的问题,我只需要写出计算Task,然后将Task分发给不同的节点,(至于Task怎么调度,怎么执行我不管)最终通过client聚合计算结果返回给用户就Ok了,因此对于大数据的处理,首先要切分,然后并行处理,最终聚合结果。
netcasewqs
其实Begin/End方式+.Net委托可以实现很轻量并类似与Future的异步机制:
//根据部门Id统计部门下所有员工的数量
int GetEmployeeCount(int departmentId)
{
Thread.Sleep(1000);
return 100;
}
//输出员工数量
void OutputEmployeeCount(int employeeCount)
{
Assert.IsTrue(employeeCount == 100);
}
Func<int, int> task = GetEmployeeCount;
int departmentId = 1;
task.BeginInvoke(departmentId, future => OutputEmployeeCount(task.EndInvoke(future)), null);
//根据部门Id统计部门下所有员工的数量
int GetEmployeeCount(int departmentId)
{
Thread.Sleep(1000);
return 100;
}
//输出员工数量
void OutputEmployeeCount(int employeeCount)
{
Assert.IsTrue(employeeCount == 100);
}
Func<int, int> task = GetEmployeeCount;
int departmentId = 1;
task.BeginInvoke(departmentId, future => OutputEmployeeCount(task.EndInvoke(future)), null);
使用future实现内置异步API
WinInet API 的异步方式使用 hh
socket api使用经验
API HOOK的实现原理
用API函数实现文件夹列表
使用Java?API压缩和?解压缩数据
使用 OpenSSL API 进行安全编程 2
API
api
如何使用东芝电脑中的内置摄像头
使用异步 I/O 大大提高应用程序的性能
使用IIS内置压缩功能优化增加网站访问速度
内置和离机闪光灯的使用小技巧
使用PS内置滤镜与调整工具制作HDR效果
详细解析电脑内置硬盘及移动硬盘的使用技巧!
详细解析电脑内置硬盘及移动硬盘的使用技巧!
使用jquery实现用户名验证
使用 Python 实现多进程
使用PuTTy实现本地文件上传下载
异步调用
百度输入法开放API 宣称可随意移植使用(图) - Qzone日志
Twitter限制API使用申请 或为调整商业模式 - Qzone日志
玩Twitter:GAE上使用GTAP搭建支持OAUTH的个性API | 西安SEO博客
Windows Socket API 使用经验 - 技术文档 - VC文档 - 网络通讯 - 立华软件园