Как писать параллельные программы на Perl?

Я должен сделать несколько задач в одном скрипте Perl. Лучше не использоватьfork или же .thread

Задача A: отправлять HTTP-запросы на сервер каждые 5 секунд. Бесконечность и не должна быть заблокирована. И если получит: '

ЗАДАЧА»задача A вызовет длительный подпроцесс, поэтому как избежать задачи A 'блока выполнения назначенияс петлей?ПАУЗА'приостановить запросОБНОВИТЬ',tell задача B сделать что-тосделать POST-запрос к серверу при получении данных из задачи B или задачи C

Задача B: делать MySQL запрос каждые 1 минуту, и в зависимости от результатов, будетtell Задача A сделать запрос POST

Задача C: принять сокетное соединение иtell Задача A или B, чтобы сделать что-то.

Три параллельных бесконечных цикла процессов и будут общаться друг с другом. Как я могу это сделать?

 Julian Fondren04 июн. 2013 г., 08:53
Вы также можетеиспользовать POE для такого рода вещей.
 amon04 июн. 2013 г., 08:32
Здесь на самом деле используются потоки, так как связь через очереди довольно проста и необязательно неблокируемая. Если бы выfork, вы можете общаться через каналы (связанные файловые дескрипторы). Если вы поместите каждую задачу в отдельный скрипт, вы можете использовать именованные каналы или сокеты. Что намного сложнее. По крайней мере, для задачи А тыd использовать потоки для достижения неблокирующих свойств (например, пять HTTP-работников, которые выполняют запросы, достаточно рабочих для затратного времени)
 ikegami04 июн. 2013 г., 09:07
... или Coro, или AnyEvent, или ... Как насчет того, чтобы нам было проще?
 ikegami04 июн. 2013 г., 08:37
Почему 1.4 нужно сделать с помощью задачи A ???
 TrueY04 июн. 2013 г., 07:58
В чем проблемаfork или терад? Они были разработаны для такого рода вещей.

Ответы на вопрос(1)

и утверждение, что этоЛучше не использовать потоки или дочерние процессы, имеет еще меньше смысла.

У вас есть три источника запросов:

Источник запроса A: отправляйте веб-запросы на сервер каждые 5 секунд.Источник запроса B. Отправляйте запрос к базе данных на сервер каждые 60 секунд.Источник запроса C: принимать запросы от сокета.

Создайте поток для каждого источника запроса. Их работа заключается исключительно в мониторинге каждого источника запроса, чтобы гарантировать, что источники проверяются, когда они должны быть проверены. Таким образом, ни один из этих потоков не должен выполнять какую-либо реальную работу. Если задача должна быть выполнена, они делегируют работу рабочему потоку. Они нет постить что угодно. Они неT записать в базу данных.

Фактические задачи (включая отправку сообщений POST и запись в базу данных) выполняются одним или несколькими рабочими потоками (на ваш выбор). Рабочие потоки получают запросы из единственной очереди Thread :: Queue, заполненной тремя источниками запросов.

Таким образом, код будет выглядеть так:

use threads;
use Thread::Queue qw( );

use constant NUM_WORKERS => 5;  # Tweak this. Can be as low as 1.

sub poll_web {
   my ($request_q) = @_;
   ... init ...
   while (1) {
      ...
      $request_q->enqueue([post => ...]);
      ...
   }
}

sub poll_db { ... }              # Just like poll_web

sub accept_connections { ... }   # Just like poll_web

sub post_handler { ... }         # Receives args passed to enqueue

{
   my $request_q = Thread::Queue->new();

   my %job_handlers = (
      post => \&post_handler,
      ...
   );

   for (1..NUM_WORKERS) {
      async {
         while (1) {
            my $job = $request_q->dequeue();
            my ($job_type, @args) = @$job;
            my $handler = $job_handlers{$job_type};
               or do { warn("Unknown job type $job_type"); next };
            $handler->(@args);
         }
      };
   }

   async { poll_web($request_q); };
   async { poll_db($request_q); };
   accept_connections($request_q);
}

Если вы хотите использовать процессы вместо потоков, измените

use threads;

в

use forks;

но продолжайте использовать Thread :: Queue.

 ikegami04 июн. 2013 г., 09:16
Обновленный ответ.
 Richard Morgan04 июн. 2013 г., 12:40
+1 за терпение, чтобы написать ответ, который подходит больше, чем один вопрос. Благодарю.

Ваш ответ на вопрос