当Parallel::Loops
与Win32::OLE
结合使用以创建多个Matlab实例时,如果我们使用
my $ML = Win32::OLE->new('Matlab.Application') or die "Cannot start MATLAB"
在每个循环中,程序崩溃,显示未处理的异常。
如果在my
之前删除$ML
,那么它可以正常运行,但在任何时候只有一个实例正在运行。
答案 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=swg21261292和http://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;');