Простой скрипт на 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 { }
пункт), так что вы могли бы также положить это в верхней части файла для ясности.