Golang est un langage de programmation développé par Google pour les applications côté serveur. Il présente les caractéristiques de puissantes performances de concurrence, il est donc de plus en plus largement utilisé dans les systèmes distribués et le développement d'applications à grande concurrence et à haute concurrence. Cet article présente principalement l'implémentation de la concurrence dans le langage Golang.
1. Concurrence et parallélisme
Avant de parler de la mise en œuvre de la concurrence par Golang, nous devons comprendre les deux concepts de concurrence et de parallélisme. La simultanéité fait référence à la capacité d'effectuer plusieurs tâches en même temps, éventuellement au sein du même programme. Le parallélisme fait référence à la capacité d'effectuer plusieurs tâches simultanément. La réalisation de la concurrence nécessite l'utilisation de threads, de processus et d'autres mécanismes du système d'exploitation, tandis que le parallélisme nécessite l'utilisation de capacités matérielles telles que des processeurs multicœurs. En termes simples, la concurrence de Golang est implémentée dans un seul thread et le parallélisme est implémenté dans plusieurs threads.
2. Le modèle de concurrence de Golang
Le modèle de concurrence de Golang est basé sur les deux concepts de Goroutine et Channel. Goroutine est un thread léger fourni par Golang, implémenté sur la base de la coroutine. Par rapport aux threads, la surcharge liée à la création et à la destruction des Goroutines est très faible, et la surcharge liée au basculement entre les Goroutines est également très faible. Par conséquent, un grand nombre de Goroutines peuvent être ouvertes pour effectuer des tâches, améliorant ainsi les performances de concurrence de l'application.
Aussi important que Goroutine est Channel. Channel est un mécanisme de communication thread-safe fourni par Golang. Grâce à Channel, les Goroutines peuvent communiquer et coordonner l'exécution pour réaliser le partage de données et le travail collaboratif, tout en évitant les problèmes tels que la concurrence qui peuvent survenir lorsque plusieurs threads sont simultanés.
3. Comment créer et appeler Goroutine
Goroutine peut être créée et appelée en utilisant le mot-clé go. Voici un exemple simple :
func main() { go func() { fmt.Println("This is a Goroutine!") }() fmt.Println("This is the main function!") time.Sleep(time.Second) }
Dans l'exemple ci-dessus, nous avons créé une Goroutine en utilisant le mot-clé go. Les fonctions de Goroutine sont implémentées à l'aide de fonctions anonymes. Avant de générer la chaîne "Ceci est une Goroutine!", le programme affichera d'abord la chaîne "Ceci est la fonction principale!". Puisque Goroutine est exécuté de manière asynchrone, l'application n'attend pas l'exécution de Goroutine, mais se ferme directement. Nous pouvons utiliser la fonction Sleep dans le package time pour faire attendre le thread pendant un certain temps afin que Goroutine ait le temps de s'exécuter.
4. L'utilisation de Channel
Channel est un mécanisme de communication thread-safe fourni par Golang. Il peut être utilisé pour synchroniser les informations et partager des données entre Goroutines afin d'éviter les problèmes de concurrence entre plusieurs Goroutines.
Utiliser Channel est très simple. Nous devons d’abord créer une chaîne. La création d'un canal nécessite de spécifier le type d'éléments dans le canal. Voici un exemple de création d'un Channel :
ch := make(chan int)
Dans cet exemple, nous utilisons la fonction make pour créer un Channel avec des éléments de type int.
Pour envoyer des données au canal, vous pouvez appeler la méthode d'envoi du canal (en utilisant l'opérateur <-), comme indiqué ci-dessous :
ch <- 10
Dans cet exemple, nous avons envoyé une donnée de type int 10 au canal. Si le canal est plein, l'opération est bloquée jusqu'à ce qu'il y ait de l'espace dans le canal.
Pour recevoir des données de Channel, vous pouvez appeler la méthode de réception de Channel (en utilisant l'opérateur <-), comme indiqué ci-dessous :
n := <-ch
Dans cet exemple, nous avons reçu une donnée de type int n de Channel. Si le canal est vide, l'opération sera également bloquée jusqu'à ce qu'il y ait des données dans le canal.
Channel a également d'autres opérations, telles que la méthode close pour fermer le Channel, la fonction len pour obtenir le nombre d'éléments dans le Channel, etc.
5. Exemple de programmation simultanée Golang
Ci-dessous, nous utilisons un exemple simple pour démontrer l'implémentation de la concurrence de Golang.
Supposons que nous devions calculer la moyenne de tous les éléments d'un tableau. En raison du grand nombre d’éléments dans le tableau, le calcul peut prendre du temps. Nous pouvons utiliser le mécanisme de concurrence de Golang pour accélérer les calculs.
Tout d'abord, nous définissons un tableau a contenant 100 éléments de type int. Ensuite, nous créons 10 Goroutines pour calculer la valeur de chaque élément d'un tableau, et enfin additionnons la somme de tous les éléments et divisons par le nombre d'éléments pour obtenir la moyenne.
func main() { a := make([]int, 100) for i := 0; i < len(a); i++ { a[i] = i } count := 10 resultChan := make(chan int, count) chunkSize := len(a) / count for i := 0; i < count; i++ { startIndex := i * chunkSize endIndex := (i + 1) * chunkSize if i == count-1 { endIndex = len(a) } go sumChunk(a[startIndex:endIndex], resultChan) } total := 0 for i := 0; i < count; i++ { total += <-resultChan } fmt.Println("Average value of array is: ", float32(total)/float32(len(a))) } func sumChunk(chunk []int, resultChan chan int) { sum := 0 for _, v := range chunk { sum += v } resultChan <- sum }
Dans cet exemple, nous définissons un tableau de type int a d'une longueur de 100. Pour un tableau a de longueur len(a), nous créons un nombre (ici 10) Goroutines pour calculer la somme de tous les éléments du tableau a. Chaque Goroutine calcule la somme d'une sous-séquence du tableau a et envoie son résultat à resultChan. Enfin, nous recevons les résultats de chaque Goroutine de resultChan et les additionnons pour obtenir la somme de tous les éléments et calculer la moyenne de tous les éléments.
En pratique, nous définissons généralement le nombre de Goroutines en fonction des besoins informatiques. Si plusieurs cœurs du processeur peuvent être utilisés, nous pouvons définir le nombre de Goroutines sur le nombre de cœurs du processeur. Sinon, nous devons définir le nombre de Goroutines nécessaires pour utiliser raisonnablement les ressources du processeur. Lorsqu'il y a trop de Goroutines, le système peut rencontrer des problèmes tels que le changement de contexte, entraînant une dégradation des performances.
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!