Raku kurss / Funkcionālā, paralēlā, reaktīvā un tīmekļa programmēšana / Paralēlā programmēšana / Kanāli
Saņemšana pēc beigām
Kas notiek, ja .receive izsaucat vairāk reižu, nekā ir
ņemamu vērtību? Atbilde ir atkarīga no tā, vai kanāls ir
aizvērts.
Ņemsim iepriekšējo ražotāja–patērētāja piemēru: fona uzdevums nosūta trīs vērtības un aizver kanālu. Ko darīt, ja patērētājs prasa ceturto?
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; # par vienu saņemšanu par daudzAizvērtā kanālā lieka saņemšana met izņēmumu
Aizvēršana neizmet jau sarindotās vērtības — trīs augstāk redzamie
.receive izsaukumi joprojām atgriež 1,
2 un 3. Bet, tiklīdz kanāls ir aizvērts
un tukšs, vairāk vērtību nekad nevar pienākt, tāpēc
Raku, tā vietā lai ļautu jums gaidīt mūžīgi, ceļ izņēmumu:
Cannot receive a message on a closed channelIzņēmums ir X::Channel::ReceiveOnClosed. Tas drīzāk
palīdz nekā kaitina: tas patērētājam nepārprotami pasaka, ka kanāls ir
iztukšots. Praksē jūs to nekad neuzskriet, patērējot ar
.list (kas pie aizvēršanas apstājas glīti) vai ciklojot
tikai tik ilgi, kamēr vērtības vēl ir, — abi paņēmieni parādīti
iepriekšējā lappusē.
Atvērtā kanālā lieka saņemšana bloķē
Ja ražotājs kanālu nekad neaizver, .receive nekādi nevar
zināt, vai vēl kāda vērtība nāk, tāpēc tā vienkārši
gaida:
my $c = Channel.new;
$c.send(1);
say $c.receive; # 1
say $c.receive; # gaida šeit — kanāls ir atvērts, bet tukšsProgramma pie otrā .receive iestrēgst, jo vērtība
varētu vēl tikt nosūtīta. Tieši par šīm briesmām brīdināja
iepriekšējā lappuse: aizmirstiet .close, un parasta
«pagaidi nākamo vērtību» pārvēršas gaidīšanā, kas nekad nebeidzas.
Tātad abi iznākumi ir pretēji, un tas ir noderīgi. Aizvērts kanāls, kad tas ir tukšs, uzreiz kļūdojas — jūs saņemat izņēmumu, ko var ieraudzīt un noķert. Atvērts kanāls turpina gaidīt — tieši pareizi, kamēr ražotājs vēl strādā, bet kluss iestrēgums, ja ražotājs klusi apstājies, neaizverot kanālu. Kanāla aizvēršana ir tieši tas, kas šo kluso iestrēgumu pārvērš skaidrā ziņā, ka straume ir beigusies.
Prakse
Jūs gaida 1 viktorīna par šī temata saturu.
Kursa navigācija
← Viktorīna — Kanāla aizvēršana | Viktorīna — Saņemšana pēc beigām →
💪 Vai arī dodieties tieši uz šīs sadaļas
vingrinājumiem.