Lär dig hur goroutiner och kanaler möjliggör effektiv samtidighet i dina Go-program.

Samtidighet är en avgörande aspekt av modern mjukvaruutveckling eftersom det gör det möjligt för program att effektivt hantera flera uppgifter samtidigt. Du kan skriva program som utför olika operationer som leder till förbättrad prestanda, lyhördhet och resursutnyttjande.

Samtidighet är en av funktionerna som är ansvariga för Gos snabba användning. Gos inbyggda stöd för samtidig programmering anses vara okomplicerat samtidigt som det hjälper till att undvika vanliga fallgropar som tävlingsförhållanden och dödlägen.

Samtidighet i Go

Go ger robust stöd för samtidighet genom olika mekanismer, alla tillgängliga i dess standardbibliotek och verktygskedja. Gå program uppnå samtidighet genom goroutiner och kanaler.

Goroutiner är lätta, oberoende exekverande funktioner som körs samtidigt med andra goroutiner inom samma adressutrymme. Goroutiner tillåter flera uppgifter att utvecklas samtidigt utan explicit trådhantering. Goroutiner är lättare än operativsystemtrådar och Go kan effektivt köra tusentals eller till och med miljontals goroutiner samtidigt.

instagram viewer

Kanaler är kommunikationsmekanismen för samordning och datadelning mellan goroutiner. En kanal är en maskinskriven kanal som tillåter goroutiner att skicka och ta emot värden. Kanaler tillhandahåller synkronisering för att säkerställa säker datadelning mellan goroutiner samtidigt som tävlingsförhållanden och andra vanliga samtidighetsproblem förhindras.

Genom att kombinera goroutiner och kanaler ger Go en kraftfull och okomplicerad samtidighetsmodell som förenklar utvecklingen av samtidiga program samtidigt som säkerhet och effektivitet bibehålls. Dessa mekanismer gör att du enkelt kan använda flerkärniga processorer och bygga mycket skalbara och lyhörda applikationer.

Hur man använder Goroutines för samtidig kodexekvering

Go runtime hanterar goroutiner. Goroutiner har sin stack, vilket gör att de kan ha ett lätt fotavtryck med en initial stackstorlek på några kilobyte.

Goroutiner multiplexeras till flera OS-trådar av Go-runtime. Go runtime schemaläggaren schemalägger dem på tillgängliga trådar genom att effektivt fördela arbetsbelastningen, vilket möjliggör samtidig körning av flera goroutiner på färre OS-trådar.

Att skapa goroutiner är enkelt. Du kommer att använda nyckelord följt av ett funktionsanrop för att deklarera goroutiner.

funchuvud() {
funktion1() // Skapa och kör goroutine för funktion1
funktion2() // Skapa och kör goroutine för funktion2

// ...
}

funcfunktion1() {
// Kod för funktion1
}

funcfunktion2() {
// Kod för funktion2
}

När programmet anropar funktion1() och funktion2() med nyckelordet kör Go runtime funktionerna samtidigt som goroutiner.

Här är ett exempel på användning av en goroutin som skriver ut text till konsolen:

paket huvud

importera (
"fmt"
"tid"
)

funcprintText() {
för jag := 1; jag <= 5; i++ {
fmt. Println("Skriver ut text", i)
tid. Sova(1 * tid. Andra)
}
}

funchuvud() {
printText() // Starta en goroutin för att köra printText-funktionen samtidigt

// Utför andra uppgifter i huvudgoroutinen
för jag := 1; jag <= 5; i++ {
fmt. Println("Utföra andra uppgifter", i)
tid. Sova(500 * tid. millisekund)
}

// Vänta tills goroutinen är klar
tid. Sova(6 * tid. Andra)
}

De printText funktionen skriver upprepade gånger ut text till konsolen med en för loop som körs fem gånger efter en fördröjning på en sekund mellan varje uttalande med tidspaketet.

De huvud funktionen startar en goroutin genom att anropa gå printText, som lanserar printText fungera som en separat samtidig goroutine som gör att funktionen kan köras samtidigt med resten av koden i huvud fungera.

Slutligen, för att säkerställa att programmet inte avslutas innan printText goroutine avslutar, den tid. Sova funktionen pausar huvudgoroutinen i sex sekunder. I verkliga scenarier skulle du använda synkroniseringsmekanismer som kanaler eller väntegrupper för att koordinera utförandet av goroutiner.

Använda kanaler för kommunikation och synkronisering

Goroutiner har inbyggt stöd för kommunikation och synkronisering genom kanaler, vilket gör skrivning samtidigt kod lättare än traditionella trådar, som ofta kräver manuella synkroniseringsmekanismer som lås och semaforer.

Du kan tänka på kanaler som pipelines för dataflöde mellan goroutiner. En goroutine kan skicka ett värde till kanalen, och en annan goroutine kan ta emot det värdet från kanalen. Denna mekanism säkerställer att datautbytet är säkert och synkroniserat.

Du kommer att använda operatör för att skicka och ta emot data via kanaler.

Här är ett exempel som visar den grundläggande användningen av kanaler för kommunikation mellan två goroutiner:

funchuvud() {
// Skapa en obuffrad kanal av typen sträng
ch := göra(chansträng)

// Goroutine 1: Skickar ett meddelande till kanalen
func() {
ch "Hej kanal!"
}()

// Goroutine 2: Tar emot meddelandet från kanalen
msg := fmt. Println (msg) // Utgång: Hej, kanal!
}

Kanalen i huvud funktion är en obuffrad kanal som heter kap skapad med göra() fungera. Den första goroutinen skickar meddelandet "Hej, kanal!" in i kanalen med hjälp av operatör, och den andra goroutinen tar emot meddelandet från kanalen som använder samma operatör. Slutligen, den huvud funktionen skriver ut det mottagna meddelandet till konsolen.

Du kan definiera maskinskrivna kanaler. Du anger kanaltypen när du skapar. Här är ett exempel som visar användningen av olika kanaltyper:

funchuvud() {
// Obuffrad kanal
ch1 := göra(chanint)

// Bufferad kanal med en kapacitet på 3
ch2 := göra(chansträng, 3)

// Skicka och ta emot värden från kanaler
ch1 42// Skicka ett värde till ch1
värde1 := // Få ett värde från ch1

ch2 "Hallå"// Skicka ett värde till ch2
värde2 := // Få ett värde från ch2
}

De huvud funktionen skapar två kanaler: ch1 är en obuffrad heltalskanal, while ch2 är en buffrad strängkanal med en kapacitet på 3. Du kan skicka och ta emot värden till och från dessa kanaler med hjälp av operator (värdena måste vara av angiven typ).

Du kan använda kanaler som synkroniseringsmekanismer för att koordinera goroutinexekveringen genom att utnyttja den blockerande karaktären hos kanaloperationer.

funchuvud() {
ch := göra(chanbool)

func() {
fmt. Println("Goroutine 1")
ch Sann// Signalavslut
}()

func() {
// Vänta på slutförandesignalen från Goroutine 1
fmt. Println("Goroutine 2")
}()

// Vänta på slutförandesignal från Goroutine 2
fmt. Println("Huvudgoroutin")
}

De kap kanalen är boolesk. Två goroutiner körs samtidigt i huvud fungera. Goroutine 1 signalerar att den är klar genom att skicka en Sann värde till kanal kap. Goroutine 2 väntar på slutförandesignalen genom att ta emot ett värde från kanalen. Slutligen väntar huvudgoroutinen på slutförandesignalen från goroutin två.

Du kan bygga webbappar i Go With Gin

Du kan bygga högpresterande webbappar i Go with Gin samtidigt som du utnyttjar Gos samtidighetsfunktioner.

Du kan använda Gin för att hantera HTTP-routning och mellanprogram effektivt. Dra nytta av Gos inbyggda samtidighetsstöd genom att använda goroutiner och kanaler för uppgifter som databasfrågor, API-anrop eller andra blockeringsåtgärder.