Di linguaggi di programmazione ne esistono a decine: alcuni sono piuttosto vecchi e scarsamente utilizzati, altri sembrano non sentire il peso degli anni, altri ancora sono stati sviluppati recuperando almeno in parte il lavoro già svolto in passato.
In un altro articolo abbiamo parlato di linguaggio macchina e delle differenze tra linguaggi compilati e interpretati.
Abbiamo spesso parlato del linguaggio di programmazione Go: nato nel 2007 e ufficialmente presentato nel 2009, è un linguaggio messo a punto da Google che risulta facile da usare, performante ed efficiente in fase di compilazione. Compilatori Go sono disponibili per le principali piattaforme tra cui Windows, macOS, Linux e in generale i sistemi Unix-like.
La sintassi di Go è vicina al C, fatta eccezione per la dichiarazione dei tipi e per la mancanza di parentesi tonde nei costrutti for e if.
Nel 2019 avevamo pubblicato un post in occasione dei primi dieci anni del linguaggio Go ricordando anche come Go fosse uno dei linguaggi di programmazione più promettenti.
Il principale vantaggio del linguaggio di programmazione Go: parallelizzazione e goroutine
In questa seconda decade degli anni 2000 diventa un’esigenza sempre più pressante imparare il linguaggio Go non certo perché viene proposto da Google, perché è ormai utilizzato per far funzionare applicazioni Web e server, perché è open source ma piuttosto perché gode di un vantaggio essenziale rispetto agli altri.
Go nasce per soddisfare le esigenze della programmazione concorrente ed è stato progettato per ottimizzare i tempi di compilazione anche su hardware modesti.
In informatica la concorrenza è una caratteristica per cui un insieme di processi o sottoprocessi (thread) siano in esecuzione nello stesso istante. Per come è stato concepito Go, è possibile portare all’estremo il concetto di parallelizzazione
Le goroutine rappresentano la spina dorsale di Go: sono costrutti facili da implementare e allo stesso tempo molto efficienti che aiutano a lavorare per thread. In altre parole, le attività da svolgere vengono suddivise su più “corsie” parallele che possono operare in modo separato senza dover necessariamente attendere la conclusione di una precedente “attività lenta”.
La parallelizzazione in Go può essere utilizzata per eseguire più operazioni contemporaneamente andando a migliorare le prestazioni del programma ed aumentandone l’efficienza.
Per questo motivo Go viene utilizzato per creare diverse tipologie di programmi, tra cui:
- Applicazioni web. Il linguaggio può essere utilizzato per creare server Web e servizi RESTful. La sua libreria standard include tutti gli strumenti necessari per lavorare con il protocollo HTTP.
- Strumenti di sistema. Viene sfruttato per creare strumenti di sistema come compilatori, interpreti dei comandi o utilità per la gestione dei file system.
- Applicazioni di rete. Viste le sue specificità, Go è molto adatto per la creazione di programmi che lavorano in rete: proxy, server di chat o programmi per il trasferimento di file.
- Microservizi. Go è sempre più usato per realizzare microservizi ovvero piccoli programmi indipendenti che lavorano insieme per fornire funzionalità complesse. Un’ottima caratteristica nell’era dell’Internet delle Cose o IoT.
Per eseguire una goroutine basta aggiungere la parola chiave go
prima della chiamata alla funzione che si desidera parallelizzare:
In questo modo la funzione chiamata miaFunzione()
viene eseguita in parallelo con il resto del programma grazie a Go.
Le goroutine possono ovviamente comunicare tra loro e coordinare il loro lavoro utilizzando i canali.
Ciascun programma Go può avere una sola goroutine principale, chiamata main goroutine: essa ha il compito di avviare tutte le altre goroutine e di terminare il programma quando tutte le altre goroutine hanno concluso il loro lavoro.
Si prenda come esempio questo codice Go
Le due goroutine task1()
e task2()
vengono eseguite in parallelo (si noti la presenza di go
nelle corrispondenti chiamate…).
Per simulare un’attività che richiede tempo, entrambe introducono artificiosamente un ritardo di 300 millisecondi.
I messaggi a video vengono stampati in ordine casuale, a seconda di quale goroutine completa prima la sua attività. In questo modo, il codice sfrutta la parallelizzazione di Go per eseguire più operazioni contemporaneamente e migliorare le prestazioni complessive del programma.
Come si vede nell’esempio, addirittura è il secondo task a mostrare per primo il messaggio “Avvio seconda attività“.
Togliendo i due go
davanti alle chiamate a task1()
e task2()
, le attività verranno eseguite in sequenza (lo si vede dall’output restituito) ma l’esecuzione del programma richiede più tempo non potendo beneficiare della parallelizzazione.
Quest’altro esempio di codice Go crea un canale che accetta numeri interi quindi utilizza due goroutine che inviano dati sul canale. Tali informazioni vengono poi stampate a video con il ciclo for finale. Come accennato, i canali Go consentono a più goroutine di comunicare tra loro e di scambiarsi dati.
Come si vede, i valori immessi sul canale figurano tutti nel momento in cui se ne richiede la stampa a video.
Parlando di CPU stress test abbiamo già spiegato quanto la ricerca dei numeri primi sia un’attività molto gravosa dal punto di vista computazionale.
Questo esempio di codice fa leva sulle goroutine per trovare i numeri primi nell’intervallo compreso tra 1 e 100.000: è però possibile modificare liberamente il range di proprio interesse.
La funzione findPrimeNumbers
viene nell’esempio eseguita come goroutine e accetta in ingresso canale e due interi come parametri (intervallo di ricerca).
Un ciclo for viene usato per iterare sugli interi nell’intervallo specificato e verificare se ogni numero è primo. Quest’ultimo controllo viene eseguito accertandosi, con un altro ciclo for, se il numero è divisibile per numeri diversi da 1 e da se stesso. Se il numero è primo viene inviato sul canale Go.
Tra le ultime righe c’è la chiama alla funzione findPrimeNumbers
che passa il canale e l’intervallo di numeri da esaminare.
L’ultimo ciclo for, a conclusione della procedura, non fa altro che prendere in esame il contenuto del canale e stamparlo a video.
Nell’esempio in figura, si vede come abbiamo provveduto a cercare i numeri primi tra 1 e 1.000.000.
Come provare gli esempi di codice Go in Windows
Per provare gli esempi, è sufficiente scaricare il linguaggio Go nella versione per Windows quindi installarlo sul proprio PC. Per impostazione predefinita Go viene caricato nella cartella C:\Program files\Go
.
Dopo aver scaricato gli esempi, è necessario rinominare i file sostituendo l’estensione .txt
con .go
.
Digitando cmd
nella casella di ricerca di Windows si può scrivere quanto segue:
A questo punto, per eseguire il codice Go, basta digitare il comando seguente:
In conclusione di questo semplice excursus, è possibile iniziare a imparare Go partendo dalle molteplici risorse di apprendimento disponibili sul sito ufficiale del progetto.