multithreading - 从 Perl 线程运行 bash 脚本

标签 multithreading bash perl

我的脚本应该有 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/

相关文章:

Java-在消费者等待并且tomcat关闭时停止线程

java - 如何在不同的线程中运行监听器或在不同的线程中进行计算

c++ - 线程分配的内存块是否与线程本身具有相同的亲缘关系,直到线程退出?

windows - Windows Server 2008 上的 Perl?

c++ - 加载主 QT/QML GUI 窗口会减慢启动画面的渲染速度

bash - 如何在 bash 中连接使用 printf 格式化的字符串

linux - 在网络命名空间中运行多个命令

linux - 有人可以告诉我错误在哪里吗

perl - Perl 中的未定义数组

regex - 如何在 perl regex 替换命令中使用 unicode 字符?