Usare le goroutine in Go

Mattepuffo's logo
Usare le goroutine in Go

Usare le goroutine in Go

Una goroutine ci permette di usare la concorrenza/ programmazione asincrona in Go.

Rispetto ad altri linguaggi ho trovato i concetti più semplici da imparare.

Una delle cose che mi è piaciuta di più è la possibilità di usare i channels per lo scambio dati tra le varie routines.

In questo articolo vediamo un paio di esempi.

Partiamo da un codice che sostanzialmente controlla se degli url sono online:

package main

import (
	"fmt"
	"net/http"
)

func main() {
	urls := []string{
		"https://google.it",
		"https://mattepuffo.com",
		"https://matteoferrone.it",
	}

	for _, url := range urls {
		checkUrl(url)
	}
}

func checkUrl(url string) {
	_, err := http.Get(url)

	if err != nil {
		fmt.Println(err)
	}

	fmt.Println(url, "OK")
}

Qui non usiamo la concorrenza, e quindi gli url vengono processati uno alla volta.

Va bene nel caso di così pochi url, ma supponiamo di averne tanti!

Possiamo fare così:

package main

import (
	"fmt"
	"net/http"
)

func main() {
	urls := []string{
		"https://google.it",
		"https://mattepuffo.com",
		"https://matteoferrone.it",
	}

	ch := make(chan string)

	for _, url := range urls {
		go checkUrl(url, ch)
	}

	for i := 0; i < len(urls); i++ {
		fmt.Println(<-ch)
	}
}

func checkUrl(url string, ch chan string) {
	_, err := http.Get(url)

	if err != nil {
		fmt.Println(err)
		ch <- "KO"
	}

	fmt.Println(url, "ONLINE")
	ch <- "OK"
}

Abbiamo usato la parola chiave go per creare una routine; ed abbiamo creato un chan (channel) per visualizzare l'output che la funzione ci restituisce.

Come ultimo esempio vediamo come continuare a eseguire richieste fino a che non decidiamo noi di interrompere il programma:

package main

import (
	"fmt"
	"net/http"
)

func main() {
	urls := []string{
		"https://google.it",
		"https://mattepuffo.com",
		"https://matteoferrone.it",
	}

	ch := make(chan string)

	for _, url := range urls {
		go checkUrl(url, ch)
	}

	for c := range ch {
		go checkUrl(c, ch)
	}
}

func checkUrl(url string, ch chan string) {
	_, err := http.Get(url)

	if err != nil {
		fmt.Println(err)
		ch <- url
	}

	fmt.Println(url, "ONLINE")
	ch <- url
}

Ovviamente vi consiglio di fare qualche modifica qua e la per capire meglio tutto il processo.

Enjoy!


Condividi

Commentami!