可以并行使用Win32 :: OLE来启动Matlab的多个实例吗?

时间:2013-04-26 20:08:10

标签: perl matlab parallel-processing ole

Parallel::LoopsWin32::OLE结合使用以创建多个Matlab实例时,如果我们使用

my $ML = Win32::OLE->new('Matlab.Application') or die "Cannot start MATLAB"

在每个循环中,程序崩溃,显示未处理的异常。

如果在my之前删除$ML,那么它可以正常运行,但在任何时候只有一个实例正在运行。

4 个答案:

答案 0 :(得分:1)

我不确定在并行循环中创建多个MATLAB COM服务器有什么好处。

默认情况下,服务器以共享模式创建,即由所有实例共享。 MATLAB引擎以单线程形式向用户公开,因此在您的情况下,所有客户端计算都是串行运行,而不是并行运行。

幸运的是,您可以在专用模式下创建MATLAB COM服务器:

Win32::OLE->new('Matlab.Application.single')

有关详细信息,请参阅this page

PS:我对Perl非常了解:)

答案 1 :(得分:0)

你真的应该展示你的完整代码。

如果您在中设置my $ML ,则传递给Parallel::Loops的匿名子例程只会在进程中设置值父母无法获得价值。

目前还不清楚您使用的是Matlab进程,但是在父进程死亡后它们将不会持续存在,这是您的主程序启动的子进程之一。

您可以尝试在循环外声明my @matlabs,然后执行

push @matlabs, Win32::OLE->new('Matlab.Application')
循环中的

。但是,如果您有许多持久 Matlab进程,为什么不只是运行一个简单的for循环?

答案 2 :(得分:0)

Parellel :: Loop测试不使用Win32 :: OLE来启动Matlab的多个实例,但是Parellel :: Forkmanager使用Amro的“单一”技巧和来自http://www.perlmonks.org/bare/?node_id=894058的线索来处理错误“CoInitialize尚未被称为”:

循环使用前

use Win32::OLE; # qw(EVENTS); #Win32::OLE(0.1709) error 0x800401f0: "CoInitialize has not been called"  
Win32::OLE->Initialize();  

并在循环内使用:

my $ML = Win32::OLE->new('Matlab.Application.single') or die "Cannot start MATLAB";  
$ML->{'Visible'}=0;  
$ML->Execute('try;cd \''.$wkdir.'\';'.$executable.' '.$file.' '.$countfile.';catch;end;quit;');  

使用OLE的目的只是使用:

system('matlab -automation -wait -r "try;cd \''.$wkdir.'\';'.$executable.' '.$file.' '.$countfile.';catch;end;quit;');  

是隐藏Matlab窗口,我们只是希望它能够完成工作,但我们获得了荣誉。使用Perl来实现并行化的matlab parfor效果,我们可以保持所有可用的CPU忙于在parellel循环之前分配任务并在该循环之后收集/组合结果。

答案 3 :(得分:0)

通过进一步的实验,发现Parallel :: Loop的错误和 Win32 :: OLE(0.1709)的错误错误0x800706be:“远程过程调用失败 Free使用Parellel :: ForkManager时,错误的池可以通过http://www-01.ibm.com/support/docview.wss?uid=swg21261292http://search.cpan.org/~gsar/libwin32-0.191/OLE/lib/Win32/OLE/TPJ.pod的建议来避免警告。所有代码都需要包含在并行循环中,并且这是工作版本:

    require Win32::OLE;
    import Win32::OLE;
    Win32::OLE->Initialize();
    no warnings qw(once); 
    $Win32::OLE::Warn = 0;
    my $ML = Win32::OLE->new('Matlab.Application.single') or die "Cannot start MATLAB";
    $ML->{'Visible'}=0;
    $ML->Execute('try;cd \''.$wkdir.'\';'.$executable.' '.$file.' '.$countfile.';catch;end;quit;');