Heim  >  Artikel  >  Backend-Entwicklung  >  Golang-Pipeline-Implementierungswarteschlange

Golang-Pipeline-Implementierungswarteschlange

WBOY
WBOYOriginal
2023-05-15 09:02:36433Durchsuche

Überblick

Golang ist eine beliebte Programmiersprache in der Branche und bietet die Vorteile von Leichtgewichtigkeit, Parallelitätssicherheit, integriertem GC, schneller Kompilierung usw. und wird häufig in Cloud Computing, Web, Webcrawlern und anderen Bereichen verwendet . Das effiziente Parallelitätsmodell von Golang ist einer der Gründe, warum Golang so beliebt ist. Der Pipeline-Mechanismus ist eine der drei Kommunikationsmethoden des Parallelitätsmechanismus von Golang. Pipes werden in ungepufferte Pipes und gepufferte Pipes unterteilt.

Im Parallelitätsmodell von Golang werden Pipelines normalerweise verwendet, um den Kommunikationsmechanismus zwischen Produzenten und Verbrauchern zu implementieren. Während Produzenten Daten überfluten, können Verbraucher die Daten aus der Pipeline abrufen und verarbeiten. In diesem Modell fungieren Rohre als Warteschlangen. Daher eignet sich der Pipeline-Mechanismus von Golang auch für die Warteschlangenimplementierung.

In diesem Artikel wird erläutert, wie Sie den Pipeline-Mechanismus von Golang zum Implementieren von Warteschlangen verwenden. Konkret schreiben wir eine gepufferte Warteschlange, die Parallelität unterstützt, und zeigen kurz, wie eine begrenzte Warteschlange mithilfe einer ungepufferten Pipe implementiert wird.

Warteschlange mit gepufferter Leitung

Die Warteschlange mit gepufferter Leitung ermöglicht es Erzeugern/Verbrauchern, weiterhin normal zu arbeiten, wenn die Produktions-/Verbrauchsgeschwindigkeit inkonsistent ist. Es hat eine feste Größe. Der Produzent wird blockiert, wenn die Warteschlange voll ist, und der Verbraucher wird blockiert, wenn die Warteschlange leer ist. In Golang können wir die Funktion make() verwenden, um gepufferte Pipes zu erstellen.

Hier ist ein einfaches Implementierungsbeispiel:

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
}

Im obigen Code verwenden wir eine Struktur zur Darstellung der Warteschlange, die eine Pipe und die maximale Kapazität der Warteschlange enthält. Mit der Funktion NewQueue() wird eine Warteschlange mit einer angegebenen maximalen Kapazität erstellt. In der Funktion Enqueue() schreiben wir Daten in die Pipe und blockieren, wenn die Pipe voll ist. In der Funktion Dequeue() lesen wir Daten aus der Pipe und blockieren, wenn die Pipe leer ist. In der Funktion main() erstellen wir eine Warteschlange mit einer maximalen Kapazität von 3 und fügen der Warteschlange drei Elemente 1, 2 und 3 hinzu. Anschließend wird die Funktion Dequeue() nacheinander aufgerufen, um Elemente aus der Warteschlange abzurufen und an die Konsole auszugeben.

Ungepufferte Pipes zur Implementierung begrenzter Warteschlangen

In Golang erfordert die Verwendung ungepufferter Pipes zur Implementierung begrenzter Warteschlangen die Hilfe des Select-Anweisungsmechanismus. Wir können die Standardanweisung in der Select-Anweisung verwenden, um die Blockierungssituation zu bewältigen, wenn die Warteschlange voll oder leer ist.

Das Folgende ist ein Beispiel für die Verwendung einer ungepufferten Pipe zur Implementierung einer begrenzten Warteschlange:

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())
        }()
    }
}

Im obigen Code verwenden wir auch eine Struktur, um eine begrenzte Warteschlange darzustellen. Im Gegensatz zu gepufferten Pipes übergeben wir beim Erstellen der Pipe nicht die maximale Kapazität der Warteschlange. In der Funktion Enqueue() verwenden wir die Select-Anweisung, um Elemente einzufügen, wenn die Pipe nicht voll ist. Wenn die Pipe voll ist, verwenden wir die Standardbedingung, die zuerst das erste Element in der aktuellen Warteschlange aus der Pipe entfernt und dann fügt hinzu. Neue Elemente werden eingefügt. Die Funktion „Dequeue()“ verwendet die SELECT-Anweisung auch, um das erste Element in der Warteschlange zurückzugeben, wenn die Pipe nicht leer ist. Wenn die Pipe leer ist, wird der Standardfall verwendet und -1 zurückgegeben.

In der Funktion main() fügen wir 10 Elemente in die Warteschlange ein und verwenden 10 Coroutinen, um die Elemente in der Warteschlange aus der Warteschlange zu entfernen. Da die Kapazität der Warteschlange 1 beträgt, sehen wir, dass die Funktion Enqueue() kontinuierlich Elemente in die Warteschlange einfügt, während die Funktion Dequeue() kontinuierlich Elemente entfernt, wenn die Warteschlange nicht leer ist. Daher ist die Ausgabe eine Reihe zufälliger Ganzzahlen.

Fazit

Durch die Einleitung dieses Artikels können wir sehen, dass es sehr einfach ist, Warteschlangen mithilfe des Golang-Pipeline-Mechanismus zu implementieren. Für eine Warteschlange mit einer gepufferten Pipe kann ihre maximale Kapazität direkt in der Funktion make() angegeben werden, während für eine ungepufferte Pipe zur Implementierung einer begrenzten Warteschlange der Select-Anweisungsmechanismus erforderlich ist. Aufgrund der Vorteile des Parallelitätsmodells von Golang ist es am effizientesten, den Golang-Pipeline-Mechanismus zum Implementieren von Warteschlangen zu verwenden.

Das obige ist der detaillierte Inhalt vonGolang-Pipeline-Implementierungswarteschlange. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn