multithreading - 如何在 Perl 中以线程安全的方式更改当前目录?

标签 multithreading perl working-directory

我正在使用 Thread::Pool::Simple 来创建一些工作线程。每个工作线程都会执行一些操作,包括调用 chdir,然后执行外部 Perl 脚本(从 jbrowse 基因组浏览器,如果重要的话)。我使用 capturex 调用外部脚本并因失败而死亡。

我发现当我使用多个线程时,事情开始变得困惑。经过一番研究。似乎某些线程的当前目录不正确。

也许chdir在线程之间传播(即不是线程安全的)? 或者也许是与capturex有关?

那么,如何安全地设置每个线程的工作目录?

** 更新 **

按照执行时更改目录的建议,我想问一下我应该如何将这两个命令传递给capturex

目前我有:

my @args = ( "bin/flatfile-to-json.pl", "--gff=$gff_file", "--tracklabel=$track_label", "--key=$key", @optional_args );
capturex( [0], @args );

如何向 @args 添加另一个命令? capturex 会继续因任何命令的错误而死亡吗?

最佳答案

我认为您可以通过放弃 IPC::System::Simple 轻松解决“在运行命令之前如何在子进程中 chdir”问题因为不是适合这项工作的工具。

而不是做

my $output = capturex($cmd, @args);

做类似的事情:

use autodie qw(open close);
my $pid = open my $fh, '-|';
unless ($pid) { # this is the child
  chdir($wherever);
  exec($cmd, @args) or exit 255;
}
my $output = do { local $/; <$fh> };
# If child exited with error or couldn't be run, the exception will
# be raised here (via autodie; feel free to replace it with 
# your own handling)
close ($fh);

如果您从 capturex 获取行列表而不是标量输出,唯一需要更改的是倒数第二行(到 my @output = <$fh>; )。

有关 fork-open 的更多信息位于 perldoc perlipc .

capture("chdir wherever ; $cmd @args") 相比,这个的好处是是它不会给 shell 机会对你的 @args 做坏事.

更新的代码(不捕获输出)

my $pid = fork;
die "Couldn't fork: $!" unless defined $pid;
unless ($pid) { # this is the child
  chdir($wherever);
  open STDOUT, ">/dev/null"; # optional: silence subprocess output
  open STDERR, ">/dev/null"; # even more optional
  exec($cmd, @args) or exit 255;
}
wait;
die "Child error $?" if $?;

关于multithreading - 如何在 Perl 中以线程安全的方式更改当前目录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3745048/

相关文章:

perl - 将 Unix `cal` 输出转换为 Latex 表代码 : one-liner solution?

c++ - 如何获取程序运行的目录?

linux - 使用自定义环境运行脚本。变种。和没有额外外壳的工作目录

javascript - node.js 中的 async/await 理解

forms - perl WWW::Mechanize Submit_form() 直接写入文件?

sql - 使用 perl/SQL 将文件插入 Postgres bytea 列

windows - VBScript当前目录+子目录?

java - 线程 : Just what is it that makes them confusing? 两个带有鼠标监听器的可运行程序

python - 如何在 Python 中使用锁来保护对象?

java - 在线程运行时更改 JProgressBar 值