История изменений
Исправление
gh0stwizard,
(текущая версия)
:
О чём это сообщение?
О том, что вы ничего не поняли в СОП. Вы процитировали Марка, это здорово.
Never call ->recv on a condition variable unless you know that the ->send method has been called on it already. This is because it will stall the whole program, and the whole point of using events is to stay interactive.
http://search.cpan.org/~mlehmann/AnyEvent-7.04/lib/AnyEvent.pm#WHAT_TO_DO_IN_...
А вот в деталях что происходит:
$ perl -MEV -MAnyEvent -e 'AE::cv->recv'
1. Заменяем вызов _poll из AnyEvent::Impl::EV
sub _poll {
EV::run EV::RUN_ONCE;
}
2. Место где происходит блокировка и съедание на 100% cpu (AnyEvent.pm)
sub AnyEvent::CondVar::Base::_wait {
EV::run EV::RUN_ONCE until exists $_[0]{_ae_sent};
}
3. Злощастный вызов
sub recv {
unless ($_[0]{_ae_sent}) {
$WAITING
and Carp::croak "AnyEvent::CondVar: recursive blocking wait attempted";
local $WAITING = 1;
$_[0]->_wait; # блокировка наступает здесь
}
#
# далее в нашем случае никогда не произойдет
#
$_[0]{_ae_croak}
and Carp::croak $_[0]{_ae_croak};
wantarray
? @{ $_[0]{_ae_sent} }
: $_[0]{_ae_sent}[0]
}
4. Совместим все выше сказанное для кратости и ясности
sub recv {
EV::run EV::RUN_ONCE until exists $_[0]{_ae_sent};
}
Теперь разберемся почему в вашем случае происходит, а в моем - нет:
$ perl -MEV -MAnyEvent -e '$cv = AE::cv; $t = AE::timer 10, 10, sub { }; $cv->recv'
EV::RUN_ONCE block at most once (wait, but do not loop)
http://search.cpan.org/~mlehmann/EV-4.15/EV.pm#BASIC_INTERFACE
А теперь слегка изменим мой код, чтобы явно доказать, что вы ничего не поняли в СОП:
$ perl -MEV -MAnyEvent -e '$cv = AE::cv; $t = AE::timer 10, 0, sub { undef $t; }; $cv->recv'
Выводы из последнего кода:
1. Первый 10 секунд нагрузка на cpu будет менее 1%, т.к. «EV::run EV::RUN_ONCE» будет ждать события от AE::timer, цитирую еще раз:
wait, but do not loop
2. Через 10 секунд мы сносим единственного «стража» и поведение резко меняется, теперь это программа не написана в стиле СОП!
EV::run EV::RUN_ONCE until exists $_[0]{_ae_sent};
Поставьте вместо EV::run EV::RUN_ONCE все что угодно и cpu будет жраться на все 100%, это просто PP!
localtime until exists $_[0]{_ae_sent};
3. Вывод: в больших программах, где используются любые другие «стражи» эта строчка «AE::cv->recv» безобидна. И она не всегда ест 100% cpu, а только тогда когда вы превратили программу во что-то другое, но не СОП.
Исправление
gh0stwizard,
:
О чём это сообщение?
О том, что вы ничего не поняли в СОП. Вы процитировали Марка, это здорово.
Never call ->recv on a condition variable unless you know that the ->send method has been called on it already. This is because it will stall the whole program, and the whole point of using events is to stay interactive.
http://search.cpan.org/~mlehmann/AnyEvent-7.04/lib/AnyEvent.pm#WHAT_TO_DO_IN_...
А вот в деталях что происходит:
$ perl -MEV -MAnyEvent -e 'AE::cv->recv'
1. Заменяем вызов _poll из AnyEvent::Impl::EV
sub _poll {
EV::run EV::RUN_ONCE;
}
2. Место где происходит блокировка и съедание на 100% cpu (AnyEvent.pm)
sub AnyEvent::CondVar::Base::_wait {
EV::run EV::RUN_ONCE until exists $_[0]{_ae_sent};
}
3. Злощастный вызов
sub recv {
unless ($_[0]{_ae_sent}) {
$WAITING
and Carp::croak "AnyEvent::CondVar: recursive blocking wait attempted";
local $WAITING = 1;
$_[0]->_wait; # блокировка наступает здесь
}
#
# далее в нашем случае никогда не произойдет
#
$_[0]{_ae_croak}
and Carp::croak $_[0]{_ae_croak};
wantarray
? @{ $_[0]{_ae_sent} }
: $_[0]{_ae_sent}[0]
}
4. Совместим все выше сказанное для кратости и ясности
sub recv {
EV::run EV::RUN_ONCE until exists $_[0]{_ae_sent};
}
Теперь разберемся почему в вашем случае происходит, а в моем - нет:
$ perl -MEV -MAnyEvent -e '$cv = AE::cv; $t = AE::timer 10, 10, sub { }; $cv->recv'
EV::RUN_ONCE block at most once (wait, but do not loop)
http://search.cpan.org/~mlehmann/EV-4.15/EV.pm#BASIC_INTERFACE
А теперь слегка изменим мой код, чтобы явно доказать, что вы ничего не поняли в СОП:
$ perl -MEV -MAnyEvent -e '$cv = AE::cv; $t = AE::timer 10, 0, sub { undef $t; }; $cv->recv'
Выводы из последнего кода:
1. Первый 10 секунд нагрузка на cpu будет менее 1%, т.к. «EV::run EV::RUN_ONCE» будет ждать события от AE::timer цитирую еще раз:
wait, but do not loop
2. Через 10 секунд мы сносим единственного «стража» и поведение резко меняется, теперь это программа не написана в стиле СОП!
EV::run EV::RUN_ONCE until exists $_[0]{_ae_sent};
Поставьте вместо EV::run EV::RUN_ONCE все что угодно и cpu будет жраться на все 100%, это просто PP!
localtime until exists $_[0]{_ae_sent};
3. Вывод: в больших программах, где используются любые другие «стражи» эта строчка «AE::cv->recv» безобидна. И она не всегда ест 100% cpu, а только тогда когда вы превратили программу во что-то другое, но не СОП.
Исходная версия
gh0stwizard,
:
О чём это сообщение?
О том, что вы ничего не поняли в СОП. Вы процитировали Марка, это здорово.
Never call ->recv on a condition variable unless you know that the ->send method has been called on it already. This is because it will stall the whole program, and the whole point of using events is to stay interactive.
http://search.cpan.org/~mlehmann/AnyEvent-7.04/lib/AnyEvent.pm#WHAT_TO_DO_IN_...
А вот в деталях что происходит:
$ perl -MEV -MAnyEvent -e 'AE::cv->recv'
1. Заменяем вызов _poll из AnyEvent::Impl::EV
sub _poll {
EV::run EV::RUN_ONCE;
}
2. Место где происходит блокировка и съедание на 100% cpu (AnyEvent.pm)
sub AnyEvent::CondVar::Base::_wait {
EV::run EV::RUN_ONCE until exists $_[0]{_ae_sent};
}
3. Злощастный вызов
sub recv {
unless ($_[0]{_ae_sent}) {
$WAITING
and Carp::croak "AnyEvent::CondVar: recursive blocking wait attempted";
local $WAITING = 1;
$_[0]->_wait; # блокировка наступает здесь
}
#
# далее в нашем случае никогда не произойдет
#
$_[0]{_ae_croak}
and Carp::croak $_[0]{_ae_croak};
wantarray
? @{ $_[0]{_ae_sent} }
: $_[0]{_ae_sent}[0]
}
4. Совместим все выше сказанное для кратости и ясности
sub recv {
EV::run EV::RUN_ONCE until exists $_[0]{_ae_sent};
}
Теперь разберемся почему в вашем случае происходит, а в моем - нет:
$ perl -MEV -MAnyEvent -e '$cv = AE::cv; $t = AE::timer 10, 10, sub { }; $cv->recv'
EV::RUN_ONCE block at most once (wait, but do not loop)
http://search.cpan.org/~mlehmann/EV-4.15/EV.pm#BASIC_INTERFACE
А теперь слегка изменим мой код, чтобы явно доказать, что вы ничего не поняли в СОП:
$ perl -MEV -MAnyEvent -e '$cv = AE::cv; $t = AE::timer 10, 0, sub { undef $t; }; $cv->recv'
Выводы из последнего кода:
1. Первый 10 секунд нагрузка на cpu будет менее 1%, т.к. «EV::run EV::RUN_ONCE» будет ждать события от AE::timer цитирую еще раз:
wait, but do not loop
2. Через 10 секунд мы сносим единственного «стража» и поведение резко меняется, теперь это программа не написана в стиле СОП!
EV::run EV::RUN_ONCE until exists $_[0]{_ae_sent};
Поставьте вместо EV::run EV::RUN_ONCE все что угодно и cpu будет жраться на все 100%, это просто PP!
localtime until exists $_[0]{_ae_sent};
3. Вывод: в больших программах? где используются любые другие «стражи» эта строчка «AE::cv->recv» безобидна. И она не всегда ест 100% cpu, а только тогда когда вы превратили программу во что-то другое, но не СОП.