La concurrence est l'une des fonctionnalités déterminantes de Go, ce qui en fait un langage fantastique pour créer des applications évolutives et hautes performances. Dans cet article, nous explorerons les Goroutines, qui vous permettent d'exécuter des fonctions simultanément dans Go, donnant ainsi à vos applications un sérieux gain d'efficacité. Que vous travailliez sur un serveur Web, un processeur de données ou tout autre type d'application, Goroutines peut vous aider à faire plus avec moins.
Voici ce que nous allons aborder :
Commençons ! ?
Les Goroutines sont des threads légers gérés par le runtime Go, vous permettant d'exécuter des fonctions simultanément. Contrairement aux threads au niveau du système d’exploitation, les Goroutines sont beaucoup moins chères et plus efficaces. Vous pouvez générer des milliers de Goroutines sans surcharger votre système, ce qui les rend idéales pour les tâches simultanées.
Créer une Goroutine est incroyablement simple : il suffit d'utiliser le mot-clé go avant un appel de fonction. Regardons un exemple rapide.
package main import ( "fmt" "time" ) func printMessage(message string) { for i := 0; i < 5; i++ { fmt.Println(message) time.Sleep(500 * time.Millisecond) } } func main() { go printMessage("Hello from Goroutine!") // This runs concurrently printMessage("Hello from main!") }
Dans cet exemple, printMessage est appelé comme Goroutine avec go printMessage("Hello from Goroutine!"), ce qui signifie qu'il s'exécutera en même temps que la fonction principale.
Étant donné que les Goroutines s'exécutent simultanément, elles peuvent terminer dans n'importe quel ordre. Pour vous assurer que toutes les Goroutines sont terminées avant de continuer, vous pouvez utiliser un WaitGroup du package de synchronisation de Go.
package main import ( "fmt" "sync" "time" ) func printMessage(message string, wg *sync.WaitGroup) { defer wg.Done() // Notify WaitGroup that the Goroutine is done for i := 0; i < 5; i++ { fmt.Println(message) time.Sleep(500 * time.Millisecond) } } func main() { var wg sync.WaitGroup wg.Add(1) go printMessage("Hello from Goroutine!", &wg) wg.Add(1) go printMessage("Hello again!", &wg) wg.Wait() // Wait for all Goroutines to finish fmt.Println("All Goroutines are done!") }
Ici, nous ajoutons wg.Add(1) pour chaque Goroutine et appelons wg.Done() lorsque la Goroutine est terminée. Enfin, wg.Wait() met la fonction principale en pause jusqu'à ce que toutes les Goroutines soient terminées.
Canaux sont le moyen intégré de Go permettant aux Goroutines de communiquer. Ils vous permettent de transmettre des données en toute sécurité entre Goroutines, garantissant ainsi qu'aucune course aux données ne se produise.
package main import ( "fmt" ) func sendData(channel chan string) { channel <- "Hello from the channel!" } func main() { messageChannel := make(chan string) go sendData(messageChannel) message := <-messageChannel // Receive data from the channel fmt.Println(message) }
Dans cet exemple, sendData envoie un message à messageChannel et la fonction principale le reçoit. Les canaux aident à synchroniser les Goroutines en bloquant jusqu'à ce que l'expéditeur et le destinataire soient prêts.
Vous pouvez également créer des canaux tamponnés qui permettent de stocker un nombre défini de valeurs dans le canal avant qu'il ne se bloque. Ceci est utile lorsque l'on souhaite gérer les flux de données sans nécessairement synchroniser chaque Goroutine.
func main() { messageChannel := make(chan string, 2) // Buffered channel with capacity of 2 messageChannel <- "Message 1" messageChannel <- "Message 2" // messageChannel <- "Message 3" // This would block as the buffer is full fmt.Println(<-messageChannel) fmt.Println(<-messageChannel) }
Les canaux tamponnés ajoutent un peu plus de flexibilité, mais il est important de gérer soigneusement la taille des tampons pour éviter les blocages.
Éviter de bloquer les Goroutines : Si une Goroutine se bloque et qu'il n'y a aucun moyen de la libérer, vous vous retrouverez dans une impasse. Utilisez des canaux ou l'annulation de contexte pour éviter cela.
Utiliser select avec les canaux : lorsque vous travaillez avec plusieurs canaux, l'instruction select vous permet de gérer le canal qui est prêt en premier, évitant ainsi un blocage potentiel.
select { case msg := <-channel1: fmt.Println("Received from channel1:", msg) case msg := <-channel2: fmt.Println("Received from channel2:", msg) default: fmt.Println("No data received") }
close(messageChannel)
Surveiller l'utilisation de la mémoire : Étant donné que les Goroutines sont si légères, il est facile d'en générer trop. Surveillez l'utilisation de la mémoire de votre application pour éviter de surcharger le système.
Utiliser le contexte pour l'annulation : lorsque vous devez annuler les Goroutines, utilisez le package contextuel de Go pour propager les signaux d'annulation.
ctx, cancel := context.WithCancel(context.Background()) defer cancel() go func(ctx context.Context) { for { select { case <-ctx.Done(): return default: // Continue processing } } }(ctx)
Les Goroutines sont une fonctionnalité puissante de Go, rendant la programmation simultanée accessible et efficace. En tirant parti des Goroutines, des WaitGroups et des canaux, vous pouvez créer des applications qui gèrent les tâches simultanément, évoluent efficacement et exploitent pleinement les processeurs multicœurs modernes.
試試看:在您自己的專案中嘗試 Goroutine!一旦掌握了它們的竅門,您就會發現它們為 Go 應用程式打開了一個充滿可能性的全新世界。快樂編碼! ?
您最喜歡的 Goroutine 用例是什麼? 請在評論中告訴我,或分享您有效使用 Goroutine 的任何其他技巧!
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!