>백엔드 개발 >Golang >golang 파이프라인 구현 대기열

golang 파이프라인 구현 대기열

WBOY
WBOY원래의
2023-05-15 09:02:36485검색

개요

업계에서 널리 사용되는 프로그래밍 언어인 Golang은 경량, 동시성 안전성, 내장 GC, 빠른 컴파일 등의 장점을 갖고 있으며 클라우드 컴퓨팅, 웹, 웹 크롤러 및 기타 분야에서 널리 사용됩니다. Golang의 효율적인 동시성 모델은 Golang이 인기를 끄는 이유 중 하나입니다. 파이프라인 메커니즘은 Golang의 동시성 메커니즘의 세 가지 통신 방법 중 하나입니다. 파이프는 버퍼되지 않은 파이프와 버퍼된 파이프로 구분됩니다.

Golang의 동시성 모델에서 파이프라인은 일반적으로 생산자와 소비자 간의 통신 메커니즘을 구현하는 데 사용됩니다. 생산자가 데이터를 넘치면 소비자는 파이프라인에서 데이터를 가져와 처리할 수 있습니다. 이 모델에서는 파이프가 대기열 역할을 합니다. 따라서 Golang의 파이프라인 메커니즘은 대기열 구현에도 적합합니다.

이 글에서는 Golang의 파이프라인 메커니즘을 사용하여 대기열을 구현하는 방법을 소개합니다. 특히, 동시성을 지원하는 버퍼링된 큐를 작성하고 버퍼링되지 않은 파이프를 사용하여 제한된 큐를 구현하는 방법을 간략하게 보여줍니다.

버퍼 파이프가 있는 큐

버퍼 파이프가 있는 큐를 사용하면 생산/소비 속도가 일관되지 않을 때 생산자/소비자가 계속 정상적으로 작동할 수 있습니다. 크기가 고정되어 있어 대기열이 가득 차면 생산자가 차단되고 대기열이 비어 있으면 소비자가 차단됩니다. Golang에서는 make() 함수를 사용하여 버퍼링된 파이프를 만들 수 있습니다.

다음은 간단한 구현 예입니다.

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
}

위 코드에서는 파이프와 대기열의 최대 용량을 포함하는 구조를 사용하여 대기열을 나타냅니다. NewQueue() 함수는 지정된 최대 용량을 가진 대기열을 생성하는 데 사용됩니다. Enqueue() 함수에서는 파이프에 데이터를 쓰고 파이프가 가득 차면 차단합니다. Dequeue() 함수에서는 파이프에서 데이터를 읽고 파이프가 비어 있으면 차단합니다. main() 함수에서 최대 용량이 3인 대기열을 만들고 대기열에 1, 2, 3개의 요소를 추가합니다. 그런 다음 Dequeue() 함수가 순서대로 호출되어 대기열에서 요소를 가져와 콘솔에 출력합니다.

버퍼링되지 않은 파이프를 사용하여 제한된 큐 구현

Golang에서 버퍼링되지 않은 파이프를 사용하여 제한된 큐를 구현하려면 select 문 메커니즘의 도움이 필요합니다. 대기열이 가득 차거나 비어 있을 때 차단 상황을 처리하기 위해 select 문의 기본 문을 사용할 수 있습니다.

다음은 버퍼링되지 않은 파이프를 사용하여 경계 큐를 구현하는 예입니다.

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

위 코드에서는 구조를 사용하여 경계 큐를 표현하기도 합니다. 버퍼링된 파이프와 달리 파이프를 생성할 때 대기열의 최대 용량을 전달하지 않습니다. Enqueue() 함수에서는 파이프가 가득 차지 않았을 때 요소를 삽입하기 위해 select 문을 사용합니다. 파이프가 가득 차면 먼저 파이프에서 현재 큐의 첫 번째 요소를 제거하는 기본 조건을 사용합니다. 추가 새 요소가 삽입됩니다. Dequeue() 함수는 또한 파이프가 비어 있지 않을 때 select 문을 사용하여 큐의 첫 번째 요소를 반환합니다. 파이프가 비어 있으면 기본 사례가 사용되고 -1이 반환됩니다.

main() 함수에서는 10개의 요소를 대기열에 삽입하고 10개의 코루틴을 사용하여 대기열의 요소를 대기열에서 제거합니다. 큐의 용량이 1이므로 Enqueue() 함수는 계속해서 큐에 요소를 삽입하고, Dequeue() 함수는 큐가 비어 있지 않을 때 계속해서 요소를 제거하는 것을 볼 수 있습니다. 따라서 출력은 일련의 임의의 정수입니다.

결론

이 글의 소개를 통해 Golang 파이프라인 메커니즘을 사용하여 대기열을 구현하는 것이 매우 간단하다는 것을 알 수 있습니다. 버퍼링된 파이프가 있는 큐의 경우 최대 용량은 make() 함수에서 직접 지정할 수 있는 반면, 버퍼링되지 않은 파이프의 경우 제한된 큐를 구현하려면 select 문 메커니즘을 사용해야 합니다. Golang 동시성 모델의 장점으로 인해 Golang 파이프라인 메커니즘을 사용하여 대기열을 구현하는 것이 가장 효율적입니다.

위 내용은 golang 파이프라인 구현 대기열의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.