Aflați cum goroutinele și canalele permit concurența eficientă în programele dvs. Go.
Concurența este un aspect crucial al dezvoltării software moderne, deoarece permite programelor să gestioneze eficient mai multe sarcini simultan. Puteți scrie programe care execută diverse operațiuni care conduc la îmbunătățirea performanței, a capacității de răspuns și a utilizării resurselor.
Concurența este una dintre caracteristicile responsabile pentru adoptarea rapidă a Go. Suportul încorporat al Go pentru programarea concomitentă este considerat simplu, contribuind în același timp la evitarea capcanelor comune, cum ar fi condițiile de cursă și blocajele.
Concurență în Go
Go oferă suport robust pentru concurență prin diferite mecanisme, toate disponibile în biblioteca sa standard și lanțul de instrumente. Go programe obținerea concurenței prin goroutine și canale.
Goroutine sunt funcții ușoare, care execută independent și care rulează concomitent cu alte goroutine în același spațiu de adrese. Goroutines permite mai multor sarcini să progreseze simultan fără o gestionare explicită a firelor. Goroutinele sunt mai ușoare decât firele de execuție ale sistemului de operare, iar Go poate rula eficient mii sau chiar milioane de goroutine simultan.
Canalele sunt mecanismul de comunicare pentru coordonarea și partajarea datelor între goroutine. Un canal este un canal tipizat care permite goroutinelor să trimită și să primească valori. Canalele oferă sincronizare pentru a asigura partajarea sigură a datelor între goroutine, prevenind în același timp condițiile de cursă și alte probleme comune de concurență.
Combinând goroutine și canale, Go oferă un model de concurență puternic și simplu, care simplifică dezvoltarea programelor concurente, menținând în același timp siguranța și eficiența. Aceste mecanisme vă permit să le utilizați cu ușurință procesoare multicore și construiți aplicații foarte scalabile și receptive.
Cum să utilizați Goroutines pentru execuția concomitentă a codului
Runtime Go gestionează goroutine. Goroutines au stiva lor, permițându-le să aibă o amprentă ușoară, cu o dimensiune inițială a stivei de câțiva kiloocteți.
Goroutinele sunt multiplexate pe mai multe fire de operare de către timpul de execuție Go. Programatorul Go runtime le programează pe firele disponibile distribuind eficient volumul de lucru, permițând execuția concomitentă a mai multor rutine pe mai puține fire de sistem de operare.
Crearea de goroutine este simplă. Veți folosi merge cuvânt cheie urmat de un apel de funcție pentru a declara goroutine.
funcprincipal() {
merge function1() // Creați și executați goroutine pentru funcția1
merge function2() // Creați și executați goroutine pentru funcția 2// ...
}funcfunctia 1() {
// Cod pentru funcția1
}
funcfunctia 2() {
// Cod pentru funcția2
}
Când programul invocă function1() și function2() cu merge cuvântul cheie, runtimeul Go execută funcțiile simultan ca goroutine.
Iată un exemplu de utilizare a unei goroutine care imprimă text pe consolă:
pachet principal
import (
"fmt"
"timp"
)funcprintText() {
pentru eu := 1; eu <= 5; i++ {
fmt. Println(„Tipărește text”, i)
timp. Dormi(1 * timp. Al doilea)
}
}funcprincipal() {
merge printText() // Porniți o rutină pentru a executa funcția printText simultan// Efectuați alte sarcini în goroutine principală
pentru eu := 1; eu <= 5; i++ {
fmt. Println(„Efectuarea altor sarcini”, i)
timp. Dormi(500 * timp. milisecundă)
}
// Așteptați să se termine goroutine
timp. Dormi(6 * timp. Al doilea)
}
The printText funcția imprimă în mod repetat un text pe consolă cu a pentru buclă care rulează de cinci ori după o întârziere de o secundă între fiecare instrucțiune cu pachetul de timp.
The principal funcția pornește o rutină prin apelare du-te printText, care lansează printText funcţionează ca o rutină concurentă separată care permite funcţiei să se execute concomitent cu restul codului din principal funcţie.
În cele din urmă, pentru a vă asigura că programul nu se închide înainte de printText finisaje goroutine, cel timp. Dormi funcția întrerupe programul principal timp de șase secunde. În scenariile din lumea reală, ați folosi mecanisme de sincronizare precum canale sau grupuri de așteptare pentru a coordona execuția goroutinelor.
Utilizarea canalelor pentru comunicare și sincronizare
Goroutines au suport încorporat pentru comunicare și sincronizare prin canale, făcând scrierea concomitentă codul mai ușor decât firele tradiționale, care necesită adesea mecanisme de sincronizare manuală, cum ar fi încuietori și semafoare.
Puteți gândi canalele ca conducte pentru fluxul de date între goroutine. O goroutine poate trimite o valoare în canal, iar o altă goroutine poate primi acea valoare de la canal. Acest mecanism asigură că schimbul de date este sigur și sincronizat.
Veți folosi operatorului să trimită și să primească date prin canale.
Iată un exemplu care demonstrează utilizarea de bază a canalelor pentru comunicarea între două goroutine:
funcprincipal() {
// Creați un canal fără tampon de tip șir
ch := face(chanşir)// Goroutine 1: Trimite un mesaj pe canal
mergefunc() {
ch "Bună, Channel!"
}()
// Goroutine 2: Primește mesajul de la canal
msg := fmt. Println (mesaj) // Ieșire: Bună, Canal!
}
Canalul din principal funcția este un canal fără tampon numit cap creat cu face() funcţie. Prima goroutină trimite mesajul „Bună ziua, Canal!” în canal folosind operator, iar a doua goroutine primește mesajul de la canal folosind același operator. În cele din urmă, cel principal funcția imprimă mesajul primit pe consolă.
Puteți defini canale tastate. Veți specifica tipul de canal la creare. Iată un exemplu care demonstrează utilizarea diferitelor tipuri de canale:
funcprincipal() {
// Canal fără tampon
ch1 := face(chanint)// Canal tamponat cu o capacitate de 3
ch2 := face(chanşir, 3)// Trimiterea și primirea valorilor de la canale
ch1 42// Trimite o valoare în ch1
valoare1 := // Primește o valoare de la ch1
ch2 "Buna ziua"// Trimite o valoare în ch2
valoare2 := // Primește o valoare de la ch2
}
The principal funcția creează două canale: ch1 este un canal întreg fără tampon, în timp ce ch2 este un canal șir tamponat cu o capacitate de 3. Puteți trimite și primi valori către și de la aceste canale folosind operator (valorile trebuie să fie de tipul specificat).
Puteți utiliza canalele ca mecanisme de sincronizare pentru coordonarea execuției goroutinei prin valorificarea naturii de blocare a operațiunilor canalului.
funcprincipal() {
ch := face(chanbool)mergefunc() {
fmt. Println(„Goroutine 1”)
ch Adevărat// Finalizarea semnalului
}()mergefunc() {
// Așteptați semnalul de finalizare de la Goroutine 1
fmt. Println(„Goroutine 2”)
}()
// Așteptați semnalul de finalizare de la Goroutine 2
fmt. Println("Goroutina principală")
}
The cap canalul este boolean. Două goroutine rulează simultan în principal funcţie. Goroutine 1 semnalează finalizarea sa trimițând a Adevărat valoare în canal cap. Goroutine 2 așteaptă semnalul de finalizare primind o valoare de la canal. În cele din urmă, goroutina principală așteaptă semnalul de finalizare de la goroutine doi.
Puteți crea aplicații web în Go With Gin
Puteți crea aplicații web de înaltă performanță în Go with Gin, utilizând în același timp funcțiile de concurență Go.
Puteți folosi Gin pentru a gestiona eficient rutarea HTTP și middleware. Valorificați suportul de concurență încorporat de la Go prin folosirea de rutine și canale pentru sarcini precum interogări de baze de date, apeluri API sau alte operațiuni de blocare.