Lær, hvordan goroutiner og kanaler muliggør effektiv samtidighed i dine Go-programmer.

Samtidighed er et afgørende aspekt af moderne softwareudvikling, da det gør det muligt for programmer effektivt at håndtere flere opgaver samtidigt. Du kan skrive programmer, der udfører forskellige operationer, der fører til forbedret ydeevne, reaktionsevne og ressourceudnyttelse.

Samtidighed er en af ​​de funktioner, der er ansvarlige for Gos hurtige adoption. Go's indbyggede understøttelse af samtidig programmering anses for at være ligetil, mens den hjælper med at undgå almindelige faldgruber som racerforhold og dødvande.

Samtidighed i Go

Go giver robust support til samtidighed gennem forskellige mekanismer, alle tilgængelige i dets standardbibliotek og værktøjskæde. Gå programmer opnå samtidighed gennem goroutiner og kanaler.

Goroutiner er lette, uafhængigt udførende funktioner, der kører samtidig med andre goroutiner inden for det samme adresseområde. Goroutiner gør det muligt for flere opgaver at udvikle sig samtidigt uden eksplicit trådstyring. Goroutiner er lettere end operativsystemtråde, og Go kan effektivt køre tusinder eller endda millioner af goroutiner samtidigt.

instagram viewer

Kanaler er kommunikationsmekanismen til koordinering og datadeling mellem goroutiner. En kanal er en maskinskrevet kanal, der tillader goroutiner at sende og modtage værdier. Kanaler leverer synkronisering for at sikre sikker datadeling mellem goroutiner og samtidig forhindre løbsforhold og andre almindelige samtidighedsproblemer.

Ved at kombinere goroutiner og kanaler giver Go en kraftfuld og ligetil samtidighedsmodel, der forenkler udviklingen af ​​samtidige programmer og samtidig opretholder sikkerheden og effektiviteten. Disse mekanismer gør det nemt at bruge dem multicore processorer og byg meget skalerbare og responsive applikationer.

Sådan bruges goroutiner til samtidig kodeudførelse

Go runtime administrerer goroutiner. Goroutiner har deres stak, hvilket gør det muligt for dem at have et let fodaftryk med en indledende stakstørrelse på et par kilobyte.

Goroutiner multiplekses til flere OS-tråde af Go runtime. Go runtime-planlæggeren planlægger dem på tilgængelige tråde ved effektivt at fordele arbejdsbyrden, hvilket muliggør samtidig udførelse af flere goroutiner på færre OS-tråde.

At skabe goroutiner er ligetil. Du vil bruge nøgleord efterfulgt af et funktionskald for at erklære goroutiner.

funcvigtigste() {
funktion1() // Opret og udfør goroutine for funktion1
funktion2() // Opret og udfør goroutine for funktion2

// ...
}

funcfunktion 1() {
// Kode for funktion1
}

funcfunktion 2() {
// Kode til funktion2
}

Når programmet starter funktion1() og funktion2() med nøgleordet, udfører Go runtime funktionerne samtidigt som goroutiner.

Her er et eksempel på brug af en goroutine, der udskriver tekst til konsollen:

pakke vigtigste

importere (
"fmt"
"tid"
)

funcprintTekst() {
til jeg := 1; jeg <= 5; i++ {
fmt. Println("Udskrivning af tekst", i)
tid. Søvn(1 * tid. Anden)
}
}

funcvigtigste() {
printText() // Start en goroutine for at udføre printText-funktionen samtidigt

// Udfør andre opgaver i hovedgoroutinen
til jeg := 1; jeg <= 5; i++ {
fmt. Println("Udførelse af andre opgaver", i)
tid. Søvn(500 * tid. millisekund)
}

// Vent på, at goroutinen er færdig
tid. Søvn(6 * tid. Anden)
}

Det printTekst funktionen udskriver gentagne gange noget tekst til konsollen med en til sløjfe, der kører fem gange efter en forsinkelse på et sekund mellem hver erklæring med tidspakken.

Det vigtigste funktion starter en goroutine ved at kalde gå udskrivTekst, som lancerer printTekst fungere som en separat samtidig goroutine, der tillader funktionen at udføre samtidig med resten af ​​koden i vigtigste fungere.

Endelig for at sikre, at programmet ikke afsluttes før printTekst goroutine afslutter, den tid. Søvn funktionen sætter hovedgoroutinen på pause i seks sekunder. I scenarier i den virkelige verden vil du bruge synkroniseringsmekanismer som kanaler eller ventegrupper til at koordinere udførelsen af ​​goroutiner.

Brug af kanaler til kommunikation og synkronisering

Goroutiner har indbygget understøttelse af kommunikation og synkronisering gennem kanaler, hvilket gør skrivning samtidig kode nemmere end traditionelle tråde, som ofte kræver manuelle synkroniseringsmekanismer som låse og semaforer.

Du kan tænke på kanaler som pipelines til dataflow mellem goroutiner. En goroutine kan sende en værdi ind i kanalen, og en anden goroutine kan modtage den værdi fra kanalen. Denne mekanisme sikrer, at dataudveksling er sikker og synkroniseret.

Du vil bruge operatør til at sende og modtage data gennem kanaler.

Her er et eksempel, der viser den grundlæggende brug af kanaler til kommunikation mellem to goroutiner:

funcvigtigste() {
// Opret en ikke-bufferet kanal af typen streng
lm := lave(chansnor)

// Goroutine 1: Sender en besked til kanalen
func() {
lm "Hej, kanal!"
}()

// Goroutine 2: Modtager beskeden fra kanalen
msg := fmt. Println (msg) // Output: Hej, kanal!
}

Kanalen i vigtigste funktion er en ikke-bufferet kanal med navnet ch skabt med lave() fungere. Den første goroutine sender beskeden "Hej, kanal!" ind i kanalen ved hjælp af operatør, og den anden goroutine modtager beskeden fra kanalen ved hjælp af den samme operatør. Endelig vigtigste funktionen udskriver den modtagne besked til konsollen.

Du kan definere indtastede kanaler. Du angiver kanaltypen ved oprettelsen. Her er et eksempel, der viser brugen af ​​forskellige kanaltyper:

funcvigtigste() {
// Ubufferet kanal
ch1 := lave(chanint)

// Bufret kanal med en kapacitet på 3
ch2 := lave(chansnor, 3)

// Sender og modtager værdier fra kanaler
ch1 42// Send en værdi ind i ch1
værdi1 := // Modtag en værdi fra ch1

ch2 "Hej"// Send en værdi ind i ch2
værdi2 := // Modtag en værdi fra ch2
}

Det vigtigste funktion opretter to kanaler: ch1 er en heltalskanal uden buffer, mens ch2 er en bufret strengkanal med en kapacitet på 3. Du kan sende og modtage værdier til og fra disse kanaler ved hjælp af operator (værdierne skal være af den angivne type).

Du kan bruge kanaler som synkroniseringsmekanismer til at koordinere udførelse af goroutine ved at udnytte den blokerende karakter af kanaloperationer.

funcvigtigste() {
lm := lave(chanbool)

func() {
fmt. Println("Goroutine 1")
lm rigtigt// Signal afslutning
}()

func() {
// Vent på færdiggørelsessignalet fra Goroutine 1
fmt. Println("Goroutine 2")
}()

// Vent på færdiggørelsessignal fra Goroutine 2
fmt. Println("Hovedgoroutine")
}

Det ch kanal er boolesk. To goroutiner løber samtidigt i vigtigste fungere. Goroutine 1 signalerer, at den er fuldført ved at sende en rigtigt værdi ind i kanalen ch. Goroutine 2 venter på færdiggørelsessignalet ved at modtage en værdi fra kanalen. Til sidst venter hovedgoroutinen på færdiggørelsessignalet fra goroutine to.

Du kan bygge webapps i Go With Gin

Du kan bygge højtydende webapps i Go with Gin, mens du udnytter Gos samtidighedsfunktioner.

Du kan bruge Gin til at håndtere HTTP-routing og middleware effektivt. Drag fordel af Gos indbyggede samtidighedsunderstøttelse ved at bruge goroutiner og kanaler til opgaver som databaseforespørgsler, API-kald eller andre blokeringsoperationer.