Go Channels Tutorial

v tomto tutoriálu se podíváme na to, jak můžete používat kanály v rámci aplikací založených na Go.

Kanály jsou trubky, které spojují mezi goroutines ve vašem Jít basedapplications, které umožňují komunikaci a následně předávání hodnot přistát z proměnných.

jsou neuvěřitelně užitečné a může vám pomoci řemeslo neuvěřitelně vysoký výkon,vysoce souběžné aplikace v Go s minimální námahou ve srovnání s otherprogramming jazyků. To v žádném případě náhoda, při navrhování thelanguage, jádro vývojáři rozhodli, že chtějí souběžnosti v theirlanguage být první třídě občan, a aby to tak jednoduché, práce s toje to možné, aniž by příliš daleko, a ne umožňuje vývojářům svobodu theyneed do práce.

schopnost plavidla souběžných systémů, takže snadno je něco, co nakreslil mi na jazyk, v první řadě, a musím říct, že to bylo absolutedelight tak daleko.

Poznámka – já bych doporučit, podívej se na můj další tutoriál ongoroutines pokud chcete learnmore o goroutines.

Cíle

na konci tohoto kurzu budete:

  • Mít solidní znalosti jak v teorii programy
  • Být schopen vytvářet jednoduché souběžné Jít aplikací, které používají programy

Předpoklady

aby bylo možné dokončit tento návod, budete potřebovat, aby splnily followingprerequisites:

  • Budete potřebovat Jít nainstalován na vašem počítači.

Video Tutorial

pokud si přejete, tento tutoriál je k dispozici ve formátu videa.

Teorie

myšlenka programy, to není nic nového, stejně jako mnoho z Go concurrencyfeatures, tyto pojmy byly předloženy od likes Hoare’sCommunicating Sekvenční Procesy (1978), CSP pro krátkodobé, a dokonce i z thelikes z Dijkstra je hlídané příkazy (1975).

vývojáři Jít, nicméně, dělal to své poslání, aby předložila theseconcepts v jednoduchým způsobem, jako je to možné umožnit programátorům createbetter, více správně, vysoce souběžných aplikací.

jednoduchý příklad

Začněme tím, že uvidíme, jak můžeme vytvořit opravdu jednoduchý příklad toho, jak to funguje v Go. Nejprve vytvoříme funkci, která zmizí a vypočítá anarbitrary, náhodnou hodnotu a předá ji zpět do proměnné kanálu zvanévalues:

hlavní.jděte

pojďme rozebrat, co se zde stalo. V naší funkci main() jsme nazvalivalues := make(chan int), toto volání efektivně vytvořilo náš nový kanál, takže bychom jej mohli následně použít v rámci našeho CalculateValue goroutine.

Poznámka – použili Jsme make při použití values kanál, likemaps a plátky, programy musí být vytvořena před použitím.

poté, co jsme vytvořili out channel, jsme zavolali defer close(values) což znamenalo uzavření našeho kanálu až do konce funkce main(). To je obvykle považováno za nejlepší postup, abychom zajistili, že se po sobě uklidíme.

Po naší výzvě k defer jsme jít na kick off naší jednotné goroutine:CalculateValue(values) kolem v naší nově vytvořené values kanál jako itsparameter. V rámci našeho CalculateValue funkce, můžeme vypočítat jeden randomvalue mezi 1-10, tohle vytisknout a pak poslat tuto hodnotu na valueskanál zavoláním values <- value.

když skočíme zpět do naší funkce main(), zavoláme value := <-values, která získá hodnotu z našeho kanálu values.

poznámka-všimněte si, jak při spuštění tohoto programu, to není immediatelyterminate. Je to proto, že akt odesílání a přijímání z kanálujsou blokovány. Naše funkce main() blokuje, dokud neobdrží hodnotu z našeho kanálu.

po provedení tohoto kódu byste měli vidět, že výstup vypadá takto:

$ go run main.goGo Channel TutorialCalculated Random Value: {} 77

shrnutí:

myChannel := make(chan int) – vytváří myChannel což je kanál typuint

channel <- value – odešle hodnoty na kanál

value := <- channel – přijímá hodnotu z kanálu

Takže, spouštění a pomocí kanálů ve vašem Jít programů vypadá celkem nekomplikovaná tak daleko, ale co v případě složitějších scénářů?

Unbuffered kanály

použití tradičního channel ve vašich goroutines může někdy vést k problémům s chováním, které možná úplně nečekáte. S tradičními kanályunbuffered, kdykoli jeden goroutine odešle hodnotu tomuto kanálu, goroutine bude následně blokovat, dokud nebude hodnota přijata z kanálu.

podívejme se na to v reálném příkladu. Pokud se podíváme na níže uvedený kód, je to velmipodobně jako kód, který jsme měli dříve. Nicméně jsme rozšířili naši funkciCalculateValue() tak, aby provedla fmt.Println poté, co odeslala svou náhodně vypočtenou hodnotu do kanálu.

v naší funkci main() jsme přidali druhé volání nago CalculateValue(valueChannel), takže bychom měli očekávat 2 hodnoty odeslané do tohoto kanálu ve velmi rychlém sledu.

hlavní.

Nicméně, když spustíte, měli byste vidět, že pouze naše první goroutines’ finalprint prohlášení je skutečně popraven:

go run main.goGo Channel TutorialCalculated Random Value: {} 1Calculated Random Value: {} 71Only Executes after another goroutine performs a receive on the channel

důvod pro toto je naše výzva k c <- value zablokoval v naší secondgoroutine a následně main() funkce uzavírá, je provedení beforeour druhé goroutine dostane šanci na dokončení jeho vlastní popravu.

Buffered Channels

způsob, jak obejít toto blokovací chování, je použít něco, co se nazývá abuffered channel. Tyto vyrovnávací kanály jsou v podstatě fronty dané velikostikteré lze použít pro komunikaci mezi goroutiny. S cílem vytvořit abuffered kanál v protikladu k bez vyrovnávací pameti kanál, dodáváme capacityargument, aby naše make příkaz:

bufferedChannel := make(chan int, 3)

změnou tohoto do vyrovnávací paměti kanálu, naše odeslání, c <- value onlyblocks v naší goroutines by kanál bude plný.

pojďme upravit náš stávající program tak, aby používal vyrovnávací kanál a podíval se na výstup. Všimněte si, že jsem přidal volání time.Sleep() v dolní části našímain() funkce za účelem líně blok main() funkce dost allowour goroutines na kompletní provedení.

hlavní.jděte

Nyní, když to provedeme, měli bychom vidět, že náš druhý goroutin skutečně pokračuje v jeho provádění bez ohledu na skutečnost, že druhý příjem nebyl volán v naší funkci main(). Díky time.Sleep() můžeme jasně vidět rozdíl mezi neblokovanými kanály a jejich blokační povahou a našimi kanály a jejich neblokovanou (pokud není plná) povahou.

Go Channel TutorialCalculated Random Value: {} 1Calculated Random Value: {} 77This executes regardless as the send is now non-blockingThis executes regardless as the send is now non-blocking

Závěr

Takže, v tomto poměrně zdlouhavý tutoriál, se nám podařilo dozvědět se o variousdistinct typy kanálů v rámci Go. Objevili jsme rozdíly mezi oběma kanály a kanály bez vyrovnávací paměti a jak bychom je mohli využít ve svůj prospěch v našich souběžných programech go.

pokud se vám tento tutoriál líbil, neváhejte a dejte mi vědět v sekci comments níže. Pokud máte nějaké návrhy, co bych mohl udělat lepšípak bych je rád slyšel v sekci komentářů níže!

Další Čtení

Pokud se vám to líbilo tento článek a chcete se dozvědět více o práci s Concurrencyin Jít, pak doporučuji vám, podívejte se na naše další články o souběžnosti:

  • Jít Mutex Tutorial
  • Go Goroutines Tutorial
  • synchronizace.Výukový Program WaitGroup

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.

Previous post Brunswick County Library System
Next post Měli Byste Malovat nebo Skvrna Skříně? Klady a zápory každého