Простой скрипт на Perl для очень быстрого цикла

Я пытаюсь заставить Perl-скрипт зацикливаться очень быстро (в Solaris).

У меня есть что-то вроде этого:

#! /bin/perl

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

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

Я хочу, чтобы скрипт perl выполнял скрипт оболочки каждые 10 микросекунд. Сценарий не завершается ошибкой, но как бы я ни изменял точность воспроизведения внутри сценария, он все еще выполняется только примерно 10 раз в секунду. Мне нужно, чтобы это зациклилось намного быстрее.

Я что-то упустил здесь? Я никогда раньше не использовал Perl, но я не могу получить скорость сна, которую хочу в Solaris, поэтому я выбрал Perl.

ТИА

Huskie.

РЕДАКТИРОВАТЬ:

Пересмотренная идея сценария благодаря комментариям пользователей - теперь я пытаюсь сделать все это в 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.

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 раз в секунду.

Узким местом является создание процессов, каналов и открытие выходного файла. Вы должны делать это не чаще, чем на каждой итерации. Вот почему вам нужно делать все на Perl, если вы хотите сделать это быстрее. Что означает: не называйте ps команда или любая другая команда. Вместо этого читайте из /proc или используйте Proc:: ProcessTable, как предлагают комментарии.

Кстати: use Оператор выполняется только один раз (это, по сути, сокращение для require заявление завернуто в BEGIN { } пункт), так что вы могли бы также положить это в верхней части файла для ясности.

Другие вопросы по тегам