Vue d'ensemble
Golang, en tant que langage de programmation populaire dans l'industrie, présente les avantages de la légèreté, de la sécurité de la concurrence, du GC intégré, de la compilation rapide, etc., et est largement utilisé dans le cloud computing, le Web, les robots d'exploration Web et d'autres domaines. . Le modèle de concurrence efficace de Golang est l’une des raisons pour lesquelles Golang est si populaire. Le mécanisme de pipeline est l'une des trois méthodes de communication du mécanisme de concurrence de Golang. Les tuyaux sont divisés en tuyaux sans tampon et en tuyaux avec tampon.
Dans le modèle de concurrence de Golang, les pipelines sont généralement utilisés pour mettre en œuvre le mécanisme de communication entre les producteurs et les consommateurs. À mesure que les producteurs inondent de données, les consommateurs peuvent obtenir les données du pipeline et les traiter. Dans ce modèle, les tuyaux agissent comme des files d'attente. Par conséquent, le mécanisme de pipeline de Golang convient également à la mise en œuvre de files d'attente.
Cet article expliquera comment utiliser le mécanisme de pipeline de Golang pour implémenter des files d'attente. Plus précisément, nous allons écrire une file d'attente tamponnée qui prend en charge la concurrence et montrer brièvement comment implémenter une file d'attente limitée à l'aide d'un canal sans tampon.
File d'attente avec tuyau tamponné
La file d'attente avec tuyau tamponné permet aux producteurs/consommateurs de continuer à travailler normalement lorsque la vitesse de production/consommation est incohérente. Il a une taille fixe, le producteur sera bloqué lorsque la file d'attente est pleine et le consommateur sera bloqué lorsque la file d'attente est vide. Dans Golang, nous pouvons utiliser la fonction make() pour créer des canaux tamponnés.
Voici un exemple d'implémentation simple :
package main import "fmt" type Queue struct { // 声明管道 items chan int // 声明队列最大容量 capacity int } func NewQueue(capacity int) *Queue { return &Queue{make(chan int, capacity), capacity} } func (q *Queue) Enqueue(item int) { q.items <- item } func (q *Queue) Dequeue() int { return <-q.items } func main() { q := NewQueue(3) q.Enqueue(1) q.Enqueue(2) q.Enqueue(3) fmt.Println(q.Dequeue()) // 1 fmt.Println(q.Dequeue()) // 2 fmt.Println(q.Dequeue()) // 3 }
Dans le code ci-dessus, nous utilisons une structure pour représenter la file d'attente, qui contient un tube et la capacité maximale de la file d'attente. La fonction NewQueue() est utilisée pour créer une file d'attente avec une capacité maximale spécifiée. Dans la fonction Enqueue(), nous écrivons des données dans le tube et bloquons si le tube est plein. Dans la fonction Dequeue(), nous lisons les données du tube et bloquons si le tube est vide. Dans la fonction main(), nous créons une file d'attente d'une capacité maximale de 3 et ajoutons trois éléments 1, 2 et 3 à la file d'attente. Ensuite, la fonction Dequeue() est appelée dans l'ordre pour obtenir des éléments de la file d'attente et les afficher sur la console.
Tubes sans tampon pour implémenter des files d'attente limitées
Dans Golang, l'utilisation de canaux sans tampon pour implémenter des files d'attente limitées nécessite l'aide du mécanisme d'instruction select. Nous pouvons utiliser l'instruction par défaut dans l'instruction select pour gérer la situation de blocage lorsque la file d'attente est pleine ou vide.
Ce qui suit est un exemple d'utilisation d'un canal sans tampon pour implémenter une file d'attente limitée :
package main import ( "fmt" "math/rand" ) type Queue struct { items chan int } func NewQueue() *Queue { return &Queue{make(chan int)} } func (q *Queue) Enqueue(item int) { select { case q.items <- item: default: <-q.items q.items <- item } } func (q *Queue) Dequeue() int { select { case item := <-q.items: return item default: return -1 } } func main() { q := NewQueue() for i := 0; i < 10; i++ { go func() { q.Enqueue(rand.Intn(100)) }() go func() { fmt.Println(q.Dequeue()) }() } }
Dans le code ci-dessus, nous utilisons également une structure pour représenter une file d'attente limitée. Contrairement aux tubes tamponnés, nous ne transmettons pas la capacité maximale de la file d'attente lors de la création du tube. Dans la fonction Enqueue(), nous utilisons l'instruction select pour insérer des éléments lorsque le canal n'est pas plein ; si le canal est plein, nous utilisons la condition par défaut, qui supprime d'abord le premier élément de la file d'attente actuelle du canal, puis ajoute De nouveaux éléments sont insérés. La fonction Dequeue() utilise également l'instruction select pour renvoyer le premier élément de la file d'attente lorsque le tube n'est pas vide, si le tube est vide, la valeur par défaut est utilisée et -1 est renvoyé ;
Dans la fonction main(), nous insérons 10 éléments dans la file d'attente et utilisons 10 coroutines pour retirer les éléments de la file d'attente. Nous pouvons voir que puisque la capacité de la file d'attente est de 1, la fonction Enqueue() insère en continu des éléments dans la file d'attente, tandis que la fonction Dequeue() supprime en continu des éléments lorsque la file d'attente n'est pas vide. Le résultat est donc une série d’entiers aléatoires.
Conclusion
A travers l'introduction de cet article, nous pouvons voir qu'il est très simple d'implémenter des files d'attente en utilisant le mécanisme de pipeline Golang. Pour une file d'attente avec un canal tamponné, sa capacité maximale peut être spécifiée directement dans la fonction make(), tandis que pour un canal sans tampon pour implémenter une file d'attente limitée, vous devez utiliser le mécanisme d'instruction select. En raison des avantages du modèle de concurrence de Golang, il est plus efficace d'utiliser le mécanisme de pipeline Golang pour implémenter les files d'attente.
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!