Ontdek hoe goroutines en kanalen efficiënte gelijktijdigheid in uw Go-programma's mogelijk maken.

Gelijktijdigheid is een cruciaal aspect van moderne softwareontwikkeling, omdat het programma's in staat stelt om efficiënt meerdere taken tegelijk uit te voeren. U kunt programma's schrijven die verschillende bewerkingen uitvoeren die leiden tot verbeterde prestaties, reactievermogen en gebruik van bronnen.

Gelijktijdigheid is een van de kenmerken die verantwoordelijk zijn voor de snelle acceptatie van Go. Go's ingebouwde ondersteuning voor gelijktijdig programmeren wordt als eenvoudig beschouwd en helpt veelvoorkomende valkuilen zoals race-omstandigheden en impasses te vermijden.

Gelijktijdigheid in Go

Go biedt robuuste ondersteuning voor gelijktijdigheid via verschillende mechanismen, allemaal beschikbaar in de standaardbibliotheek en toolchain. Ga programma's gelijktijdigheid bereiken via goroutines en kanalen.

Goroutines zijn lichtgewicht, onafhankelijk uitvoerende functies die gelijktijdig met andere goroutines binnen dezelfde adresruimte worden uitgevoerd. Met Goroutines kunnen meerdere taken tegelijkertijd worden uitgevoerd zonder expliciet threadbeheer. Goroutines zijn lichter dan threads van het besturingssysteem en Go kan efficiënt duizenden of zelfs miljoenen goroutines tegelijk uitvoeren.

instagram viewer

Kanalen zijn het communicatiemechanisme voor coördinatie en gegevensuitwisseling tussen goroutines. Een kanaal is een getypt kanaal waarmee goroutines waarden kunnen verzenden en ontvangen. Kanalen zorgen voor synchronisatie om veilige gegevensuitwisseling tussen goroutines te garanderen en race-omstandigheden en andere veelvoorkomende concurrency-problemen te voorkomen.

Door goroutines en kanalen te combineren, biedt Go een krachtig en ongecompliceerd concurrency-model dat de ontwikkeling van gelijktijdige programma's vereenvoudigt met behoud van veiligheid en efficiëntie. Deze mechanismen stellen u in staat om gemakkelijk te gebruiken multicore-processoren en bouw zeer schaalbare en responsieve applicaties.

Goroutines gebruiken voor gelijktijdige code-uitvoering

De Go-runtime beheert goroutines. Goroutines hebben hun stack, waardoor ze een lichtgewicht voetafdruk hebben met een initiële stackgrootte van enkele kilobytes.

Goroutines worden door de Go-runtime op verschillende OS-threads gemultiplext. De Go-runtimeplanner plant ze op beschikbare threads door de werklast efficiënt te verdelen, waardoor gelijktijdige uitvoering van meerdere goroutines op minder OS-threads mogelijk is.

Het maken van goroutines is eenvoudig. Je gebruikt de gaan trefwoord gevolgd door een functieaanroep om goroutines te declareren.

funcvoornaamst() {
gaan functie1() // Creëer en voer goroutine uit voor functie1
gaan functie2() // Creëer en voer goroutine uit voor functie2

// ...
}

funcfunctie1() {
// Code voor functie1
}

funcfunctie2() {
// Code voor functie2
}

Wanneer het programma aanroept functie1() En functie2() met de gaan sleutelwoord, voert de Go-runtime de functies gelijktijdig uit als goroutines.

Hier is een voorbeeld van het gebruik van een goroutine die tekst naar de console afdrukt:

pakket voornaamst

importeren (
"fmt"
"tijd"
)

funcprintTekst() {
voor ik := 1; ik <= 5; ik++ {
fmt. Println("Tekst afdrukken", i)
tijd. Slaap(1 * tijd. Seconde)
}
}

funcvoornaamst() {
gaan printTekst() // Start een goroutine om de printText-functie gelijktijdig uit te voeren

// Voer andere taken uit in de hoofdroutine
voor ik := 1; ik <= 5; ik++ {
fmt. Println("Andere taken uitvoeren", i)
tijd. Slaap(500 * tijd. milliseconde)
}

// Wacht tot de goroutine klaar is
tijd. Slaap(6 * tijd. Seconde)
}

De printTekst functie drukt herhaaldelijk wat tekst af naar de console met a voor lus die vijf keer wordt uitgevoerd na een vertraging van een seconde tussen elke instructie met het tijdpakket.

De voornaamst functie start een goroutine door te bellen ga printText, die de lanceert printTekst functioneren als een afzonderlijke gelijktijdige goroutine waarmee de functie gelijktijdig kan worden uitgevoerd met de rest van de code in het voornaamst functie.

Ten slotte, om ervoor te zorgen dat het programma niet wordt afgesloten voordat de printTekst goroutine-afwerkingen, de tijd. Slaap functie pauzeert de hoofdroutine gedurende zes seconden. In real-world scenario's zou je synchronisatiemechanismen zoals kanalen of wachtgroepen gebruiken om de uitvoering van goroutines te coördineren.

Kanalen gebruiken voor communicatie en synchronisatie

Goroutines hebben ingebouwde ondersteuning voor communicatie en synchronisatie via kanalen, waardoor schrijven gelijktijdig wordt code eenvoudiger dan traditionele threads, waarvoor vaak handmatige synchronisatiemechanismen nodig zijn, zoals sloten en semaforen.

U kunt kanalen zien als pijplijnen voor gegevensstromen tussen goroutines. Eén goroutine kan een waarde naar het kanaal sturen en een andere goroutine kan die waarde van het kanaal ontvangen. Dit mechanisme zorgt ervoor dat gegevensuitwisseling veilig en gesynchroniseerd is.

Je gebruikt de operator om gegevens via kanalen te verzenden en te ontvangen.

Hier is een voorbeeld dat het basisgebruik van kanalen voor communicatie tussen twee goroutines demonstreert:

funcvoornaamst() {
// Maak een niet-gebufferd kanaal van het type string
ch := maken(kansnaar)

// Goroutine 1: Stuurt een bericht naar het kanaal
gaanfunc() {
ch "Hallo, kanaal!"
}()

// Goroutine 2: ontvangt het bericht van het kanaal
bericht := fmt. Println (bericht) // Uitvoer: Hallo, kanaal!
}

Het kanaal in de voornaamst functie is een niet-gebufferd kanaal met de naam ch gemaakt met de maken() functie. De eerste goroutine stuurt het bericht "Hello, Channel!" in het kanaal met behulp van de operator, en de tweede goroutine ontvangt het bericht van het kanaal met dezelfde operator. eindelijk, de voornaamst functie drukt het ontvangen bericht af naar de console.

U kunt getypeerde kanalen definiëren. U specificeert het kanaaltype bij het maken. Hier is een voorbeeld dat het gebruik van verschillende kanaaltypen laat zien:

funcvoornaamst() {
// Niet-gebufferd kanaal
ch1 := maken(kanint)

// Gebufferd kanaal met een capaciteit van 3
ch2 := maken(kansnaar, 3)

// Verzenden en ontvangen van waarden van kanalen
1l 42// Stuur een waarde naar ch1
waarde1 := // Ontvang een waarde van ch1

ch2 "Hallo"// Stuur een waarde naar ch2
waarde2 := // Ontvang een waarde van ch2
}

De voornaamst functie creëert twee kanalen: 1l is een niet-gebufferd integer kanaal, terwijl ch2 is een gebufferd stringkanaal met een capaciteit van 3. U kunt waarden naar en van deze kanalen verzenden en ontvangen met behulp van de operator (de waarden moeten van het opgegeven type zijn).

U kunt kanalen gebruiken als synchronisatiemechanismen voor het coördineren van goroutine-uitvoering door gebruik te maken van de blokkerende aard van kanaalbewerkingen.

funcvoornaamst() {
ch := maken(kanboel)

gaanfunc() {
fmt. Println("Goroutine 1")
ch WAAR// Signaal voltooiing
}()

gaanfunc() {
// Wacht op het voltooiingssignaal van Goroutine 1
fmt. Println("Goroutine 2")
}()

// Wacht op voltooiingssignaal van Goroutine 2
fmt. Println("Hoofdroutine")
}

De ch kanaal is booleaans. Twee goroutines lopen gelijktijdig in de voornaamst functie. Goroutine 1 signaleert de voltooiing ervan door een WAAR waarde in kanaal ch. Goroutine 2 wacht op het voltooiingssignaal door een waarde van het kanaal te ontvangen. Ten slotte wacht de hoofdgoroutine op het voltooiingssignaal van goroutine twee.

U kunt web-apps bouwen in Go With Gin

U kunt krachtige web-apps bouwen in Go met Gin terwijl u gebruikmaakt van de gelijktijdigheidsfuncties van Go.

U kunt Gin gebruiken om HTTP-routering en middleware efficiënt af te handelen. Profiteer van Go's ingebouwde gelijktijdigheidsondersteuning door goroutines en kanalen te gebruiken voor taken zoals databasequery's, API-aanroepen of andere blokkeerbewerkingen.