Kurso de Raku / Funkcia, samtempa, reaktiva kaj reta programado / Samtempa programado / Kanaloj
Ricevi post la fino
Kio okazas, se vi vokas .receive pli da fojoj ol estas
valoroj por preni? La respondo dependas de tio, ĉu la kanalo estis
fermita.
Prenu la ekzemplon produktanto–konsumanto el antaŭe: fona tasko sendas tri valorojn kaj fermas la kanalon. Kio, se la konsumanto petas kvaran?
my $c = Channel.new;
start {
$c.send($_) for 1..3;
$c.close;
}
say $c.receive; # 1
say $c.receive; # 2
say $c.receive; # 3
say $c.receive; # unu ricevo tro multeSur fermita kanalo, kroma ricevo ĵetas escepton
Fermo ne forĵetas la valorojn jam envicigitajn — la tri vokoj de
.receive supre ankoraŭ redonas 1,
2 kaj 3. Sed post kiam la kanalo estas fermita
kaj malplena, neniuj pliaj valoroj povas iam alveni, do
anstataŭ lasi vin atendi eterne, Raku levas escepton:
Cannot receive a message on a closed channelLa escepto estas X::Channel::ReceiveOnClosed. Tio estas
helpa prefere ol ĝena: ĝi diras al la konsumanto, senmiskompreneble, ke
ĝi malplenigis la kanalon. Praktike vi evitas iam trafi ĝin, konsumante
per .list (kiu haltas nete ĉe la fermo) aŭ buklante nur dum
valoroj restas — ambaŭ montritaj sur la antaŭa paĝo.
Sur malfermita kanalo, kroma ricevo blokas
Se la produktanto neniam fermas la kanalon, .receive
havas nenian manieron scii, ĉu alia valoro ankoraŭ venos, do ĝi simple
atendas:
my $c = Channel.new;
$c.send(1);
say $c.receive; # 1
say $c.receive; # atendas ĉi tie — la kanalo estas malfermita sed malplenaLa programo pendas ĉe la dua .receive, ĉar valoro
eble ankoraŭ estos sendita. Jen la danĝero, pri kiu la antaŭa
paĝo avertis: forgesu .close, kaj normala «atendu la sekvan
valoron» fariĝas atendo, kiu neniam finiĝas.
Do la du rezultoj estas maloj, en utila maniero. Fermita kanalo malsukcesas rapide, kiam ĝi estas malplena — vi ricevas escepton, kiun vi povas vidi kaj kapti. Malfermita kanalo daŭre atendas — precize ĝuste dum produktanto ankoraŭ laboras, sed silenta pendo, se la produktanto senbrue ĉesis sen fermi. Fermi la kanalon estas precize tio, kio transformas tiun silentan pendon en klaran signalon, ke la fluo finiĝis.
Praktiko
Vin atendas 1 kvizo pri la enhavo de ĉi tiu temo.
Kursa navigado
← Kvizo — Fermi kanalon | Kvizo — Ricevi post la fino →
💪 Aŭ iru rekte al la ekzercoj de ĉi tiu
sekcio.