本周文件交换精选

我们最好的用户提交

信号量POSIX和Windows

肖恩本周的选择是信号量POSIX和Windows通过安德鲁聪明

背景

我一直在和一些人合作,帮助他们并行多个外部程序的模拟。外部程序可以通过它的COM API在Windows上使用actxserver.这是并行计算的理想候选者,因为模拟需要几分钟到几小时的时间来运行,并且需要在运行之间没有依赖关系的不同配置下运行。

我的第一次尝试是用parfor循环,并行地循环配置。第一次还能用,但第二次就坏了,而且仍然不可靠。问题是我打不开actxserver同时从多个并行的工作人员,因为竞态条件遇到。

因此,挑战是:如何强制每个并行工作人员打开actxserver在不同的时间,最好是在另一个人完成之后。

做这个的方法是信号量, MATLAB没有内置的。信号量用于控制对共享资源的访问。我模糊地记得以前在File Exchange上看到过这个,并检查了我的“每周精选”候选列表,果然,它就在那里,等待一个用例!

使用信号量

请注意要使用信号量,需要使用以下命令进行编译:

墨西哥人- o- vsemaphore.c

我将首先从客户端MATLAB创建信号量。平行工人会在打开之前抓住它actxserver然后将其释放。第一个要执行的worker将获取信号量,使其他worker进入first - in - first - out队列以重复这个过程。经过几秒钟的初始化时间后,所有的工作人员将并行地运行冗长的模拟。

打开并行计算池。这个池有两个工人,因为我有一个双核笔记本电脑。

gcp
ans = Pool with properties: Connected: true NumWorkers: 2 Cluster: local attachdfiles: {} IdleTimeout: 90 minutes (s)(剩余85分钟)SpmdEnabled: true

创建键值为1的信号量。这里的值很重要,用1。

semkey = 1;信号量(“创建”semkey 1)

运行parfor循环

parfor2 = 1:4试一试信号量(“等待”semkey) disp(字符串(“迭代”) + ii +”开始,“+字符串(datetime (“现在”)))暂停(2)%代理的actxserver()信号量(“职位”semkey) disp(字符串(“迭代”) + ii +的完成:+字符串(datetime (“现在”)))%在这里运行模拟%如果出现错误,释放信号量信号量(“职位”semkey)结束结束
迭代2 Started: 08-Feb-2017 11:09:34迭代2 Finished: 08-Feb-2017 11:09:34迭代1 Started: 08-Feb-2017 11:09:37迭代3 Finished: 08-Feb-2017 11:09:37迭代4 Started: 08-Feb-2017 11:09:39迭代4 Finished: 08-Feb-2017 11:09:39

如果你看一下时间,你会看到迭代2开始于32秒,并在2秒后结束(parfor迭代不会按排序顺序运行)。迭代3在迭代2之后立即开始,当它完成时,迭代1开始。迭代4在迭代1完成后开始。

这是一个带注释的图片:

清理后。

信号量(“破坏”semkey)

我能够在短短几分钟内得到这个工作,但确实吸取了一些教训的艰难的方式。有几点需要注意:

  • 使用try / catch你正在做的事情。如果进程失败,您希望释放信号量,以解除对其他工作线程的阻塞。如果发生错误,这可能会导致挂起,因为在持有其他工作人员时,循环将永远不会完成。如果达到此状态,则从任务管理器强制终止并行池。
  • 使用关键= 1值= 1递增关键如果你有多个信号量。我给安德鲁的唯一建议是在帮助中把这一点讲得更清楚一点。

评论

试试吧,让我们知道你的想法在这里或者离开评论安德鲁。

发布与MATLAB®R2016b

|
  • 打印
  • 发送电子邮件

评论

要留下评论,请点击在这里登录到您的MathWorks帐户或创建一个新帐户。