What is Coro?
Cooperative Threads. Coroutine, сопрограмма, «корутина»
- компонент программы, который поддерживает множество входных точек , остановку и продолжение выполнения с сохранением определённого состояния.
В Coro — «корутины» представлены модулями Coro::State, и высокоуровневым Coro.
Cooperative Threads.
Cooperative Threads.use Coro; async { print "async 1\n"; cede; print "async 2\n";};print "main 1\n";cede;print "main 2\n";cede;
Async - Создание корутины
Тело корутины
Main корутина
Cooperative Threads.
Cede, yield — передача управления
Main корутина
use Coro; async { print "async 1\n"; cede; print "async 2\n";}; print "main 1\n";cede;print "main 2\n";cede;
Cooperative Threads. cede — перемещает «корутину» в
конец очереди и вызывает schedulle. schedulle — вызывает шедулер, он
выбирает следующую "корутину" из очереди и передает выполнение ей. Если очередь пуста, - то передается выполнение $Coro::idle.
Deadlock. Deadlock - ситуация в многозадачной
среде, при которой несколько процессов находятся в состоянии бесконечного ожидания ресурсов, захваченных самими этими процессами.
В Coro — это состояние, когда нет «корутин» готовых к выполнению. Ситуация обрабатывается в $Coro::idle.
Deadlock.
use Coro; my $wakeme = $Coro::current; async { $wakeme->ready if 0.5 > rand; }; schedule;
Deadlock.
FATAL: deadlock detected. PID SC RSS USES Description Where 31976480 -C 19k 0 [main::] [program:9] 32223768 UC 12k 1 [Coro.pm:691] 32225088 -- 2068 1 [coro manager] [Coro.pm:691] 32225184 N- 216 0 [unblock_sub scheduler] -
Channel. Channel, канал — модель
межпроцессного взаимодействия и синхронизации через передачу сообщений.
В Coro — представлен модулем Coro::Channel, реализован с помощью Coro::Semaphore
Channel.
Channel.use Coro;my $chan = new Coro::Channel 2;# $chan async {
while(my $val = $chan->get){warn "chan out:" . $val;
}};$chan->put($_) for(1..3);
Канал на 2 элемента
Ждем данные
Кладем данные в канал
The Real World!
Event Loop.
use Coro;use Coro::AnyEvent;async {
Coro::AnyEvent::sleep 4;warn "sleep 4";
};Coro::AnyEvent::sleep 5;warn "sleep 5";
Event Loop.
Event Loop. AnyEvent - the DBI of event loop. Coro::Socket — non-blocking socket-I/O. Coro::AIO — truly asynchronous file and
directory I/O. Coro::Signal - thread signals. Coro::Semaphore - counting
semaphores. Coro::LWP — non-blocking LWP.
AnyEvent::HTTP http_get "http://mail.ru", rouse_cb; my ($data, $hdr) = rouse_wait; return undef if $hdr->{Status} =~ m/^2/; #Работаем с телом ответа
Отдаёт управлениеВозвращает управление
AnyEvent my $int_w = AnyEvent->signal (
signal => "INT", cb => Coro::rouse_cb );
Coro::rouse_wait; #Обрабатываем сигнал.
Coro::Generator Generator, генератор — одним из
способов реализации итераторов является использование сопроцедур, которые могут возвращать управление (и вычисленные результаты) несколько раз, запоминая своё состояние и точку возврата в предыдущем вызове.
Coro::Generator
use Coro::Generator; # import 'generator' and 'yield'my $even = generator { my $x = 0; while(1) { $x += 2; yield $x; }};# This will print even numbers from 2..20for(1..10) { print $even->() . "\n";}
тело генератора
yield — сохранение состояния
Coroutine - wikipedia: Сопрограмма Deadlock - wikipedia: Взаимная блокировка
Generator - wikipedia: Итератор Coro - metacpan: Coro
Coro asynchronous - slideshare
The end.