LINUX.ORG.RU

perl как реализовать прерывание бесконечного цикла для выполнения куска кода?

 


0

2

Есть бесконечный цикл while. В нем принимаются и отправляются сообщения от модуля, выполнение цикла блокируется до появления сообщения от модуля. Нужно по таймеру (как в Delphi) выполнять еще кусок кода параллельно этому циклу, с возвратом в него. Данные между этим кодом и кодом в while будут общими.
Спасибо за подсказки или примеры кода.

★★★★

Последнее исправление: cetjs2 (всего исправлений: 2)

goto. А вообще, ты изначально сделал что-то неправильно, раз тебе нужен бесконечный цикл while.

anonymous
()
Ответ на: комментарий от Vlad-76

может быть мне нужно генерить несколько прерываний с разным интервалом.и выполнять разные куски кода

Vlad-76 ★★★★
() автор топика

Запускай параллельный тред с таким же бесконечным циклом, который будет выполнять этот кусок кода с заданными таймаутами на каждой итерации.

Hater ★★
()

Достаточно много разных вариантов ващет, удобный зависит от API:

0). просто запустить 2 треда с бесконечными циклами

Но лучше если модуль при наличии у него сообщений пихал бы event в fd, тогда можно просто использовать poll/select.

qnikst ★★★★★
()
Ответ на: комментарий от monk

Действительно проще некуда, пока работает как и планировалось. Спасибо!

Vlad-76 ★★★★
() автор топика
Ответ на: комментарий от monk

сделал два threads. Объявил хэш. В одной thread пишу в хэш в другой читаю. Но ничего не читается. Как организовать доступ к общему хэшу, данным между threads?

#!/usr/bin/perl

use threads;

my %H_AC =();

threads->create(sub {
   my $c = 0;
   while(1) {
        $c++;
        sleep(1);
        every_01sec_run();
        $H_AC{$c} = $c ;
    }
});

threads->create(sub {

   while(1) {
        sleep(10);
        every_10sec_run();
        print "печать хэша\n";
        for my $key ( keys %H_AC ) {
            my $value = $H_AC{$key};
            print "$key => $value\n";
        }
    }
});

while(1) { # ОСНОВНОЙ ЦИКЛ
    sleep 13;
    print "sleep 13\n";
}

sub every_01sec_run(){
    print "sleep 1\n";

}

sub every_10sec_run(){
    print "sleep 10\n";
}

Vlad-76 ★★★★
() автор топика
Последнее исправление: Vlad-76 (всего исправлений: 3)
Ответ на: комментарий от Vlad-76

Читай мануал, тебе нужен threads::shared (или как-то так).

P.S. Есть альтернатива для событий ядра с возможностью прерывания, обычно это работа с сокетами. Это событийное программирование: AnyEvent, EV. Другой вариант это использовать ассемблерную вставку jmp, см. модуль Coro. Но если ты с потоками не разобрался, думаю это тебе не нужно. Хотя, может найдется время и желание вникнуться :)

gh0stwizard ★★★★★
()
Ответ на: комментарий от Vlad-76

Если по-простому, то после my %H_AC =(); добавь share(%H_AC);

Если в ключах и значениях хэша нет ссылок на другие переменные, то этого хватит. Подробнее http://perldoc.perl.org/threads/shared.html

monk ★★★★★
()
Последнее исправление: monk (всего исправлений: 1)
Ответ на: комментарий от gh0stwizard

где ж разобрался, первый раз в жизни столкнулся. буду читать мануал

Vlad-76 ★★★★
() автор топика
Ответ на: комментарий от monk

планирую использовать между threads и основным алгоритмом структуру хеш хешей,массивов. Как внутри хеш хранит хеши не знаю, через ссылки или еще как. Буду пробовать ну и читать.

Vlad-76 ★★★★
() автор топика
Последнее исправление: Vlad-76 (всего исправлений: 1)

Может форк и не-блокирующееся общение между процессами?

http://pragmaticperl.com/issues/04/pragmaticperl-04-anyevent-и-fork.html#.U86...

Тут и бесконечный цикл появляется естественным образом. Многие костыли убрали. Канал общения процессов проще, не надо городить костыли с shared-тредами.

outtaspace ★★★
()
Ответ на: комментарий от outtaspace

Может форк и не-блокирующееся общение между процессами?

А как тогда хэш между процессами передавать?

monk ★★★★★
()
Ответ на: комментарий от Vlad-76

структуру хеш хешей,массивов

Могу только предложить отображать на обычный хэш.

То есть вместо $H_AC{$a}{$b}[$c] пиши $H_AC{«$a_$b_$c»}. Тогда будет работать

monk ★★★★★
()

Threads зло. Я бы попытался перепилить модуль на event-driven, в крайнем можно запускать модуль в отдельном процессе

disarmer ★★★
()
Ответ на: комментарий от monk

Да легко, сериализация/десереализация, не вижу в этом проблемы. У ТСа видимо не настолько хайлоад, чтобы это стало узким местом архитектуры.

outtaspace ★★★
()
Ответ на: комментарий от monk

костыль, структура данных будет неоднородна и будет гемморойно разбирать ключ

Vlad-76 ★★★★
() автор топика
Ответ на: комментарий от outtaspace

нагрузки сильной не планируется, пока по крайней мере. Что такое сериализация и обратный процесс?

Vlad-76 ★★★★
() автор топика
Ответ на: комментарий от Vlad-76

Можешь перловую структуру данных представить как JSON, тогда дочерний процесс будет передавать родителю данные в этом формате. В родителе этот JSON преобразуется в перловую структуру данных. Задача решена.

outtaspace ★★★
()

ещё наверное можно SIGVTALRM, если очень хочется решить задачу именно таким образом.

wakuwaku ★★★★
()
Ответ на: комментарий от wakuwaku
#!/usr/bin/perl
use Time::HiRes qw ( setitimer ITIMER_VIRTUAL time );

$SIG{VTALRM} = sub { print time, "\n" };
setitimer(ITIMER_VIRTUAL, 10, 2.5);

while(1) {
    sleep 10;
    print "Sleep 10\n";
}

на perl 5.8.8 из коробки на Centos 5.9 не работает

Vlad-76 ★★★★
() автор топика
Ответ на: Всё просто от Olegymous

Модуль который ждет сообщения во время выполнения обработчика alarm отключается от сервера.

Vlad-76 ★★★★
() автор топика
Ответ на: комментарий от Vlad-76

не помню точно, но если внутренние хеши тоже шаред объявлять?

bvn13 ★★★★★
()
Ответ на: комментарий от Olegymous

Нашел в модуле как отключить блокировку ожидания сообщений.пока на этом остановился. модуль ESL для freeswitch

Vlad-76 ★★★★
() автор топика
Ответ на: комментарий от Vlad-76

В моей сишечке таймеры в бизилупе отрабатывают корректно.

wakuwaku ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.