我的脚本应该有 n 个子例程 (my_proc) 同时运行,每个子例程都运行 bash 脚本,并且一个子例程 (check_procs) 检查子例程是否已完成。
use strict;
use threads;
use threads::shared;
my %proc_status :shared;
my %thr;
foreach my $i (1,2,3,4) {
$proc_status{$i}=0;
}
sub my_proc {
my $arg=shift(@_);
while (1) {
sleep(2);
print "Proc $arg Started\n";
#exec("/bin/bash","sleep_for_10_sec.bash") or die("Can't exec"); # case 1
#`sleep_for_10_sec.bash &`; # case 2
print "Proc $arg Finished\n";
{
lock(%proc_status);
$proc_status{$arg}=1;
}
}
}
sub check_procs {
my $all_finished;
while (! $all_finished) {
sleep 5;
print "CHECK: \n";
$all_finished=1;
foreach my $num (1,2,3,4) {
if ($proc_status{$num} == 1) {
print "CHECK: procedure $num has finished\n";
} else {
$all_finished=0;
}
}
}
print "All jobs finished\n";
}
foreach my $num (1,2,3,4) {
$thr{"$num"} = new threads \&my_proc,$num;
}
my $thr_check= new threads \&check_procs;
$thr_check->join();
这是 sleep_for_10_sec.bash
ls
# bunch of other stuff
sleep 10
echo "finished sleep"
我不希望my_proc subs等待“sleep_for_10_sec.bash”命令被执行,浏览后我发现#case1或# case2 应该可以工作,但它们都失败了。
#case1 的输出:
Proc 1 Started
[ls result]
finsihed sleep
#case2 的输出:
Proc 1 Started
Proc 2 Started
Proc 3 Started
Proc 4 Started
CHECK:
CHECK:
Proc 4 Finished
Proc 2 Finished
Proc 3 Finished
Proc 1 Finished
Proc 3 Started
Proc 1 Started
Proc 2 Started
Proc 4 Started
CHECK:
CHECK: procedure 1 has finished
CHECK: procedure 2 has finished
CHECK: procedure 3 has finished
CHECK: procedure 4 has finished
但我期望这样的事情:
Proc 1 Started
Proc 2 Started
Proc 3 Started
Proc 4 Started
Proc 1 Finished
Proc 1 Started
Proc 3 Finished
Proc 3 Started
Proc 4 Finished
Proc 4 Started
Proc 2 Finished
Proc 2 Started
CHECK:
CHECK:
CHECK:
CHECK: procedure 1 has finished
CHECK: procedure 2 has finished
CHECK: procedure 3 has finished
CHECK: procedure 4 has finished
实际上,如果将输出重定向到“> log”,我会得到想要的结果,但无论如何之后:
Proc 1 Started
Proc 2 Started
Proc 3 Started
Proc 4 Started
它等待“sleep_for_10_sec.bash”完成。
这是我使用“thread”和“exec”的第一个项目,有人可以帮助我吗?
最佳答案
exec
不应与线程结合使用。 exec
在当前进程中启动一个新程序,因此当您从一个线程调用 exec
时,线程正在执行的程序就会消失。由于线程没有要执行的程序,因此 exec
也会杀死线程。
我不清楚为什么情况 2 不起作用(编辑:请参阅下面 ikegami 的评论)。我认为它会启动该进程,在后台运行它,并允许 Perl 线程立即继续。它似乎没有这样做,但这段代码会:
system("/bin/bash sleep_for_10_sec.bash &"); # case 3
关于multithreading - 从 Perl 线程运行 bash 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45598358/