我正在开发一个MATLAB项目,我想让两个MATLAB实例并行运行并共享数据。我将调用这些实例MAT_1
和MAT_2
。更具体地说,系统的架构是:
MAT_1
按顺序处理图像,使用imread
逐个读取图像,然后使用imwrite
输出每个图像的结果。MAT_2
使用MAT_1
读取imread
输出的图片,并将结果输出到其他地方。我认为我需要解决的一个问题是保证MAT_2
在MAT_1
完全写入后MAT_1
读取MAT_1
的图像输出。
我的问题是:
flock
的东西,但由MATLAB直接提供,并且可在多个平台上运行,例如Windows和Linux)。如果没有,您是否知道我可以使用任何第三方库在MATLAB中构建此机制?为什么我要求MAT_2
和MAT_2
以并行线程运行?:
MAT_1
中的处理平均速度较慢(并且更容易崩溃),而MAT_1
的输出会提供其他程序和流程(包括人工检查)不需要等待MAT_2
完成其工作。
答案 0 :(得分:7)
我会使用信号量来接近这个;根据我的经验,PCT同步速度过慢。
dfacto(另一个答案)为MATLAB提供了很好的信号量实现,但它不适用于MS Windows;我改进了这项工作,以便这样做。改进后的工作如下:http://www.mathworks.com/matlabcentral/fileexchange/45504-semaphoreposixandwindows
这比与Java,.NET,PCT或文件锁接口相比,性能更好。这不使用并行计算工具箱(PCT),并且AFAIK信号量功能无论如何都不在PCT中(令人费解的是他们将其排除在外!)。可以使用PCT进行同步,但我在其中尝试的所有内容都非常慢。
要将这个高性能信号量库安装到MATLAB中,请在MATLAB解释器中运行: mex -O -v semaphore.c
您需要安装C ++编译器才能将semaphore.c编译为二进制MEX文件。然后可以从MATLAB代码中调用该MEX文件,如下例所示。
用法示例:
function Example()
semkey=1234;
semaphore('create',semkey,1);
funList = {@fun,@fun,@fun};
parfor i=1:length(funList)
funList{i}(semkey);
end
end
function fun(semkey)
semaphore('wait',semkey)
disp('hey');
semaphore('post',semkey)
end
答案 1 :(得分:4)
就个人而言,我会使用并行处理工具箱。
据我所知,在Matlab中没有直接的方法来获得系统范围的文件锁。但是,为了确保Matlab#2仅在文件写完时读取Matlab#1的输出,我建议在写完文件results_1.mat
后,Matlab#1写入第二个文件{{1} },这是一个空文本文件。由于第二个文件是在第一个文件之后写入的,因此它的存在表示结果文件已被写入。因此,您可以搜索扩展名为results_1.finished
的文件,即finished
,并使用dir('*.finished')
获取您要使用Matlab#2加载的.mat文件的名称。
答案 2 :(得分:2)
我不确定您是否在寻找仅限matlab的解决方案,但我刚刚提交了一个用于Matlab的信号量包装器。它作为通用信号量工作,但它的设计主要考虑了sharedmatrix。
Mathworks接受提交后,我将更新我的研究组blog上的链接。
请注意,此mex文件是POSIX信号量功能的包装器。因此,它可以在Linux,Unix,MacOS中运行,但不会在Windows上开箱即用。它可以在针对cygwin库编译时起作用。
答案 3 :(得分:1)
我认为除了使用特定于操作系统的锁之外,还有一种万无一失的方式。一种方法可能是让MAT_1做:
imwrite(fileName);
movefile(fileName, completedFileName);
让MAT_2只处理completedFileName。
答案 4 :(得分:1)
看到您的编辑后,一个不涉及使用任何工具箱的简单解决方案如下:
由于MAT_2
比MAT_1
慢得多,因此请延迟MAT_2
。即,在MAT_1
完成处理后开始说5张图像左右。如果您执行此操作,MAT_2
将永远不会遇到MAT_1
,因此永远不会处于必须“等待”来自MAT_1
的图片的情况。
我仍然不清楚你问题中的一些事情:
MAT_1
按顺序处理图像,但是否必须?换句话说,它们的处理顺序是否重要?MAT_2
读取MAT_1
的输出...是否必须按照MAT_1
完成的顺序或可以是任何顺序?MAT_2
使用imread
读取图像并将其输出到其他位置。是否有任何理由无法将任务合并到MAT_1
中? 在任何情况下,您都可以使用并行计算工具箱实现某种形式的执行阻止;但不是使用parfor
循环(这是大多数人使用的循环),而是必须创建分布式作业(example)。
需要注意的重要一点是,每个工作人员(实验室)都有labindex
,您可以使用labSend
将数据从工作人员1(相当于MAT_1
)发送给工作人员2 (相当于MAT_2
),然后使用labReceive
接收它。来自labReceive
的文档:
此功能会阻止实验室中的执行,直到发送实验室中发生相应的labSend调用。
这就是您想要对MAT_1
和MAT_2
进行的操作。
另一种方法是在当前会话中生成一个额外的worker,但只将MAT_1
执行的任务分配给它。然后,您为任务设置FinishedFcn
属性以执行MAT_2
执行的功能集,但我不推荐它,因为我不认为这是FinishedFcn
的意图,我不知道在某些情况下它是否会破裂。
答案 5 :(得分:0)
我还建议您查看并行处理工具箱中的内容,您希望的功能应该放在某处。我认为这比尝试同步两个MATLAB实例更简洁(除非你被迫使用两个实例)。
在奇怪的情况下,没有这样的东西,你也可以看看不同的环境来实现你想要的东西。这可能是一种解决方法,但您始终可以将MATLAB代码与其他语言(例如Java,.NET,C,...)连接,并使用您习惯使用的功能。使用Java,您可以确信您的解决方案是独立于平台的,.NET仅适用于Windows(至少与MATLAB结合使用)。