Scrivere il tuo primo programma Go concorrente su Ubuntu
Il linguaggio di programmazione Go di Google è stato introdotto nel 2009 e nel 2012 ha raggiunto il suo stato ufficiale v1.0. Negli anni intervenuti, molto è cambiato, incluso il modo in cui il linguaggio viene installato. All’inizio, non c’erano distribuzioni binarie ufficiali e dovevi costruire Go dal codice sorgente, che era il metodo raccomandato poiché il linguaggio cambiava frequentemente, oppure utilizzare un pacchetto precompilato per la tua distribuzione Linux. All’epoca, il supporto per Windows era limitato così come il supporto per architetture CPU diverse da Intel.
Le cose sono migliorate notevolmente da allora. Per Linux, ci sono due modi semplici per installare Go. Scarica la build binaria ufficiale per Linux dalla pagina di download di Go oppure opta per un pacchetto precompilato per la tua distribuzione Linux. Il modo più semplice per installare Go su Ubuntu è utilizzare apt-get:
sudo apt-get install golangUna volta installato Go, puoi iniziare a sviluppare programmi. Uno dei programmi Go più semplici è il classico programma “Hello World!”. Utilizzando un editor di testo, crea un file chiamato “ hellomte.go “ con il seguente breve codice Go:
package main
import "fmt"
func main(){
fmt.Println("Hello Make Tech Easier!")
}Dalla versione v1.0 di Go, la necessità di comandi di compilazione e collegamento individuali è stata rimossa e i vecchi comandi 8g e 8l sono stati sostituiti dal comando go.
Per eseguire hellomte.go, apri un terminale e cambia directory nella cartella che contiene il file di codice sorgente, quindi digita:
go run hellomte.goQuesto compilerà ed eseguirà il programma Go, ma non produrrà un binario eseguibile. Per creare un binario e poi eseguirlo, utilizza il comando go build:
go build hellomte.go
./hellomteIl potere della concorrenza
Una delle caratteristiche distintive del linguaggio di programmazione Go è il suo supporto per la concorrenza, che consente a un programma di lavorare con più attività contemporaneamente. Il parallelismo, che è simile alla concorrenza, consente a un programma di eseguire molte attività simultaneamente, ma la concorrenza va un passo oltre in quanto consente a queste attività separate di comunicare e interagire. Di conseguenza, Go consente ai programmatori di utilizzare una varietà di diversi design concorrenti, inclusi pool di lavoratori, pipeline (dove un’attività avviene dopo un’altra) e attività di sfondo sincrone o asincrone. La base di questa concorrenza è la goroutine abbinata a channels e all’istruzione select di Go.
Ecco un semplice programma Go che stampa una stringa più volte utilizzando una goroutine concorrente:
package main
import(
"fmt"
"time"
)
func say(s string){
for i := 0; i < 5; i++ {
fmt.Println(s)
}
}
func main(){
go say("Hello Make Tech Easier!")
fmt.Println("Sleep a little...")
time.Sleep(100 * time.Millisecond)
}La funzione say() esegue semplicemente un ciclo per stampare la stringa (parametro s) cinque volte. La cosa interessante è come viene chiamata quella funzione. Invece di chiamare semplicemente say("Hello Make Tech Easier!"), la parola chiave go è posta davanti alla chiamata della funzione. Questo significa che la funzione verrà eseguita come un’attività separata. Il resto della funzione main() quindi dorme un po’ per dare tempo alla goroutine di completarsi.
L’output potrebbe sorprenderti:

Come puoi vedere, la funzione say() viene eseguita come una goroutine e mentre viene impostata, il resto della funzione main() continua, stampando “Sleep a little…” e poi andando a dormire. A quel punto, la goroutine è attiva e inizia a stampare la stringa cinque volte. Infine, il programma termina una volta raggiunto il limite di timeout.
Canali
Le goroutines possono comunicare utilizzando i canali. Un canale apre una linea di comunicazione tra due parti diverse di un programma Go. Tipicamente, una funzione verrà chiamata come una goroutine e se ha bisogno di restituire dati (ad esempio da un’operazione di rete), può utilizzare un canale per trasmettere quei dati. Se un’altra parte del programma Go sta aspettando quei dati, dormirà fino a quando i dati non saranno pronti. I canali vengono creati utilizzando la funzione make() e possono essere passati come parametri alle goroutines.
Considera questo codice:
package main
import(
"fmt"
)
func say(s string, c chan int){
var i int
for i = 0; i < 5; i++ {
fmt.Println(s)
}
c <- i
}
func main(){
c := make(chan int)
go say("Hello Make Tech Easier!", c)
sts := <- c
fmt.Println(sts)
}La funzione say() è molto simile al primo esempio con l’eccezione che il secondo parametro è un canale e che dopo aver stampato la stringa, il numero di iterazioni verrà inviato attraverso il canale tramite la riga di codice c <- i.
La funzione principale crea un canale, avvia la funzione say() come una goroutine e poi aspetta che i dati arrivino attraverso il canale, sts := <- c prima di stampare il risultato.
Conclusione
Il linguaggio Go ha fatto progressi significativi negli ultimi anni, se non lo hai guardato di recente, forse ora è un buon momento!