我正在尝试使用apache和mod_perl2构建一个在ubuntu机器上运行的简单Web服务。该服务运行mpirun
并返回调用的输出。
我通过Web浏览器调用apache响应处理程序。问题是mpirun
命令似乎挂起了。
重要: 使用apache,mod_perl和openmpi运行Ubuntu(12.04.4)的服务器上会出现此问题。当我在我的Mac(Macos 10.9.3)上运行它时,它工作正常,并返回mpirun。在两台机器上,openmpi安装在相同版本(1.6.5)
中这是我的mod_perl处理程序:
package MyHandler;
use Apache2::Const '-compile' => 'OK';
sub handler {
my $command = "mpirun -np 4 echo test";
my $out = qx($command);
print $out;
return Apache2::Const::OK;
}
1;
mpirun工作似乎没有完成。 ps aux | grep mpirun
给了我这个:
www-data 24023 0.0 0.1 23600 2424 ? S 13:02 0:00 mpirun -np 4 echo test
当我执行kilall -9 mpirun
时,服务会返回结果。
没有错误写入apache错误日志。
这是我尝试/测试的内容:
mpirun -np 4 echo test
www-data
命令生成正确的输出
mpirun
:按照Sergei的建议使用IPC::Run
和IPC::Run3
,我也尝试使用管道,但每次mpirun都没有完成。ompi_info --param mpi all
的输出,mac和ubuntu,但没有发现差异任何想法为什么mpirun会挂在我的情况下,或者知道如何调试它?
修改
我试图按照hrunting的建议使用Apache2::SubProcess。这里的代码遵循链接中的简单示例:
package MyHandler;
use Apache2::SubProcess ();
use Apache2::Const '-compile' => 'OK';
use Apache2::Request;
use Config;
use constant PERLIO_IS_ENABLED => $Config{useperlio};
sub handler {
my $r = shift;
my $command = "mpirun -np 4 echo test";
my ($in_fh, $out_fh, $err_fh) = $r->spawn_proc_prog($command);
$r->content_type('text/plain');
my $output = read_data($out_fh);
my $error = read_data($err_fh);
print "output : $output \n";
print "error : $error \n";
return Apache2::Const::OK;
}
# helper function to work w/ and w/o perlio-enabled Perl
sub read_data {
my ($fh) = @_;
my $data;
if (PERLIO_IS_ENABLED || IO::Select->new($fh)->can_read(10)) {
$data = <$fh>;
}
return defined $data ? $data : '';
}
1;
这对我不起作用。从浏览器调用处理程序时,我得到输出:
output :
error :
和ps aux
告诉我mpirun没有运行。
如何进一步了解如何调试此问题并让mpirun
使用我的配置?
答案 0 :(得分:1)
看看Apache2::SubProcess
。当您在mod_perl处理程序中运行外部进程时,Apache内存,I / O和进程管理就会发挥作用。请记住,您的代码在Apache本身内运行,并且受Apache环境的影响。 Apache2::SubProcess
模块旨在使exec()
- 和system()
样式调用在Apache中正常工作。
请注意,模块文档概述了处理不同Perl配置的注意事项。
答案 1 :(得分:0)
尝试使用IPC :: Run或IPC :: Run3来运行命令。
答案 2 :(得分:0)
Capture::Tiny
适合我。我不确定它在mod_perl
下是否能正常工作(它可能与请求和响应的文件句柄交互不当)但它作为常规脚本工作正常:
use Capture::Tiny 'capture';
my ( $stdout, $stderr, $exit ) = capture {
system( qw(mpirun -np 4 echo test) );
};
print "stdout: $stdout\n";
print "stderr: $stderr\n";
print "exit: $exit\n";
打印:
stdout: test
test
test
test
stderr:
exit: 0