【问题标题】:Simple PERL script to loop very quickly快速循环的简单 PERL 脚本
【发布时间】:2014-11-28 09:10:43
【问题描述】:

我正在尝试让 perl 脚本快速循环(在 Solaris 中)。

我有这样的事情:

#! /bin/perl

while ('true')
{
 use strict;
 use warnings;
 use Time::HiRes;

 system("sh", "shell script.sh");
 Time::HiRes::usleep(10);
}

我希望 perl 脚本每 10 微秒执行一次 shell 脚本。该脚本不会失败,但无论我在脚本中更改多少 usleep 的精度,该脚本仍然每秒仅执行大约 10 次。我需要它比这更快地循环。

我在这里遗漏了一些基本的东西吗?我以前从未使用过 perl,但在 Solaris 中无法获得我想要的睡眠速度,所以我选择了 perl。

TIA

哈士奇。

编辑:

感谢用户 cmets 修改了脚本创意 - 我现在正尝试在 perl 中完成这一切,但惨遭失败! 基本上我正在尝试运行 PS 命令来捕获进程 - 如果该进程存在,我想捕获该行并输出到一个文本文件。

#! /bin/perl

while ('true')
{
 use strict;
 use warnings;
 use Time::HiRes;

 open(PS,"ps -ef | grep <program> |egrep -v 'shl|grep' >> grep_out.txt");
 Time::HiRes::usleep(10);
}

这会返回以下错误:

Name "main::PS" used only once: possible typo at ./ps_test_loop.pl line 9.

【问题讨论】:

  • shell script.sh有多长?
  • 您将无法在许多计算机上每秒创建 100,000 个进程...您将需要更改 script.sh 以便它在自身内部循环运行而不退出,然后执行sleep 在每个循环的末尾。这样您就可以创建一个运行时间较长的进程,而不是每秒运行 100,000 个。
  • Shell 脚本并不是特别快,因为它们往往会启动外部进程来执行最琐碎的任务。您可能需要用 Perl 甚至 C 重写脚本才能达到 100000 次/秒。
  • 小评论:use strict; use warnings; 行应该直接在#!/bin/perl 下,这样那些编译指示就会立即打开。您也可以通过open(my $ps, "ps -ef | grep &lt;program&gt; |egrep -v 'shl|grep' &gt;&gt; grep_out.txt"); 来消除警告。

标签: perl shell loops sleep usleep


【解决方案1】:

瓶颈在于进程、管道的创建和输出文件的打开。您最多应该这样做一次,而不是在每次迭代中都这样做。这就是为什么如果你想加快速度,你需要在 Perl 中做所有事情。这意味着:不要调用ps 命令或任何其他命令。相反,按照 cmets 的建议,从 /proc 读取或使用 Proc::ProcessTable

顺便说一句:use 语句 is 只执行一次(它本质上是包裹在 BEGIN { } 子句中的 require 语句的简写),所以你不妨把它放在为了清楚起见,放在文件的顶部。

【讨论】:

    【解决方案2】:

    这是一个纯粹的 perl 程序(不启动任何外部进程),它查找运行某些特定可执行文件的进程:

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    my $cmd = 'lxc-start';
    
    my $cmd_re = qr|/\Q$cmd\E$|;
    
    $| = 1;
    
    while (1) {
        opendir PROC, "/proc" or die $!;
        while (defined(my $pid = readdir PROC)) {
            next unless $pid =~ /^\d+$/;
            if (defined(my $exe = readlink "/proc/$pid/exe")) {
                if ($exe =~ $cmd_re) {
                    print "pid: $pid\n";
                }
            }
        }
        closedir PROC;
        # sleep 1;
    }
    

    在我的电脑上,它以 250 次/秒的速度运行。

    【讨论】:

    • 这将是理想的,但我也试图查看传递给进程的变量的值。我已经测试了这个例子 - 我认为我应该用我希望拾取的进程名称替换我的 $cmd 是否正确?如果是这样,我尝试将其替换为“grep”,并从另一个会话运行 grep,但脚本没有拾取它。
    猜你喜欢
    • 2013-09-02
    • 1970-01-01
    • 1970-01-01
    • 2018-03-10
    • 2019-05-11
    • 2010-12-19
    • 1970-01-01
    • 1970-01-01
    • 2011-05-08
    相关资源
    最近更新 更多