并行编程(Future)

并行编程(Future),第1张

说到并行,常见的几种模式 “回调驱动(多线程环境下)”、“消息/事件驱动(Actor模型中)。

回调是最常见的异步并发模式,它有即时性高、接口设计简单等有点。但相对于Future,其缺点也非常明显。

首先,多线程环境下的回调一般是在触发回调的模块线程中执行的,这就意味着编写回调方法时通常必须考虑线程互斥问题

其次,回调方式接口的提供者在本模块的线程中执行用户应用的回调也是相对不安全的,因为你无法确定它会花费多长时间或出现什么异常,从而可能间接导致本模块的即时性和可靠性受影响;

再者,使用回调接口不利于顺序流程的开发,因为回调方法的执行是孤立的,要与正常流程汇合是比较困难的。因此回调接口适合于在回调中只需要完成简单任务,并且不必与其它流程汇合的场景。

Future对象本身可以看作是一个显式的引用,一个对异步处理结果的引用,可以通过调用Future.isDone()判断引用的对象是否就绪,并采取不同的处理;而后一种情况则只需调用get()或

get(long timeout, TimeUnit unit)通过同步阻塞方式等待对象就绪。实际运行期是阻塞还是立即返回就取决于get()的调用时机和对象就绪的先后了.

除了上面提到的基础形态之外,Future还有丰富的衍生变化,这里就列举几个常见的。

与一般的Future不同,Lazy Future在创建之初不会主动开始准备引用的对象,而是等到请求对象时才开始相应的工作。因此,Lazy Future本身并不是为了实现并发,而是以节约不必要的运算资源为出发点,效果上与Lambda/Closure类似。例如设计某些API时,你可能需要返回一组信息,而其中某些信息的计算可能会耗费可观的资源。但调用者不一定都关心所有的这些信息,因此将那些需要耗费较多资源的对象以Lazy Future的形式提供,可以在调用者不需要用到特定的信息时节省资源。

另外Lazy Future也可以用于避免过早的获取或锁定资源而产生的不必要的互斥。

Promise可以看作是Future的一个特殊分支,常见的Future一般是由服务调用者直接触发异步处理流程,比如调用服务时立即触发处理或 Lazy Future的取值时触发处理。但Promise则用于显式表示那些异步流程并不直接由服务调用者触发的情景。例如Future接口的定时控制,其异步流程不是由调用者,而是由系统时钟触发,再比如淘宝的分布式订阅框架提供的Future式订阅接口,其等待数据的可用性不是由订阅者决定,而在于发布者何时发布或更新数据。因此,相对于标准的Future,Promise接口一般会多出一个set()或fulfill()接口。

常规的Future是一次性的,也就是说当你获得了异步的处理结果后,Future对象本身就失去意义了。但经过特殊设计的Future也可以实现复用,这对于可多次变更的数据显得非常有用。例如前面提到的淘宝分布式订阅框架所提供的Future式接口,它允许多次调用waitNext()方法(相当于Future.get()),每次调用时是否阻塞取决于在上次调用后是否又有数据发布,如果尚无更新,则阻塞直到下一次的数据发布。这样设计的好处是,接口的使用者可以在其任何合适的时机,或者直接简单的在独立的线程中通过一个无限循环响应订阅数据的变化,同时还可兼顾其它定时任务,甚至同时等待多个Future。简化的例子如下:

for () {

schedule = getNextScheduledTaskTime()

while(schedule >now()) {

try {

data = subscription.waitNext(schedule - now())

processData(data)

} catch(Exception e) {...}

}

doScheduledTask()

}

【原文来自: http://www.cnblogs.com/uptownBoy/articles/1772483.html 】

我们下面以C 语言为例。

具体语法规则可参看《高性能计算并行编程技术-MPI 并行程序设计》一书。

mpicc -o outfilename cpi.c

其中outfilename 为编译后的输出文件,cpi.c 为源代码.

可将cpi.c 下载后上传的自己目录下编译.

例如:mpicc -o cpi cpi.c

如没有安装OpenPBS 则:

mpirun -np 4 cpi

否则:(一般安装了)

之后需写一作业提交脚本.例如:submit 内容如下:

#PBS -l nodes=nodes number

#PBS -N jobname#PBS -j oecd /home/xmin/Project

/usr/local/bin/mpiexec cpi

其中 #PBS -l nodes=nodes number 为指定几个节点计算.如: nodes=4

#PBS -N jobname 为用户命名的提交作业名称.如: #PBS -N xmin

#PBS -j oe 为结果和错误输出同文件.如无此项则分别在两个文件中.

cd /home/xmin/Project 编译后的输出文件所在路径(从根目录开始).

/usr/local/bin/mpiexec cpi 为mpiexec 所在路径.

下面是完整例子:

#PBS -l nodes=4

#PBS -N xmin#PBS -j oecd /home/xmin/Project

/usr/local/bin/mpiexec cpi

提交脚本如下:

qsub submit得到如下:3565.isc.math.nankai.edu.cn

此为你的作业编号.

这样你就可得到类似xmin.o2666 的文件,打开即可看到结果.

你还可以查询作业提交情况.命令如下:qstat

学习编程有两种情况:

1、你有语言基础:如果你有一门语言熟练或者精通,那么你完全有能力自学。因为编程的思想都是相同的。

2、如果你没有语言基础:那么建议你去找一个质量比较好的培训机构参加培训!!这样会有助于你早日进入这个行业,并在这里有个较好的发展!!!


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11291883.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-15
下一篇 2023-05-15

发表评论

登录后才能评论

评论列表(0条)

保存