Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > use Coro


Автор: Pfailed 14.12.2010, 19:13
Недавно обнаружил для себя замечательный модуль Coro.
Привлекло внимание его краткое описание:
Цитата

the only real threads in perl


Обрадовавшись, что кто-то запилил более годные треды для perl принялся изучать документацию.
Но всё оказалось не так просто, как хотелось бы. На самом деле Coro оказался не модулем реализующим создание потоков, в его привычном понимании. Coro -- ни что иное, как продвинутая реализация http://ru.wikipedia.org/wiki/Сопрограмма, т.е. таких подпрограмм, из которых можно выйти в каком-то её месте, выполнить другую часть программы, а затем вновь вернуться к тому, на чём приостановилось выполнение подпрограммы (этакий goto без тормозов). Помимо этого в Coro есть менеджер созданных сопрограмм, который эффективно переключается между ними в нужные моменты времени, обеспечивая ту саму псевдопараллельность выполения.
Таким образом Coro очень хорошо подходит для работы с сокетами: в то время когда какой-либо из сокетов ожидает прихода данных менеджер сопрограмм переключается на другие сопрограммы и в итоге тормоза одного сокета не останавливают всю программу.
В чём преимущество Coro перед событийно-ориентированными модулями вроде AnyEvent и POE ил простого цикла select? А в том, что если у вас уже есть рабочий код, то вам скорее всего придётся его переписать практически полностью, чтобы воспользоваться этими модулями, но не в случае с Coro.
Простой пример. У меня есть модуль Net::Proxy::Type для определения типа прокси  (который ничего не знает про параллельную обработку нескольких прокси) и несколько тысяч прокси тип которых нужно определить. 

Код

use strict;
use Coro::Select;
use Coro;
use Net::Proxy::Type;

my @proxylist = (...);
my @workers;

for (1 .. $cfg->{workers}) {
    push @workers, async {
        my @list = @_;
        my $pc = Net::Proxy::Type->new();
        foreach my $proxy (@list) {
            my $pt = $pc->get();
            # ...
            # profit
        }
    } splice(@proxylist, 0, $cfg->{proxy_per_worker});
}

$_->join foreach @workers;


При этом потребление памяти очень небольшое, форками и модулем threads такого не добиться, но в тоже время не придётся переписывать рабочий код, как в случае с AnyEvent.
Кстати Coro написал Marc Lehmann, являющийся помимо этого автором AnyEvent и многих других полезных вещей.
За истину не ручаюсь, т.к. только начал с этим знакомиться.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)