>  기사  >  백엔드 개발  >  golang의 Barrier에 대해 이야기 해 봅시다.

golang의 Barrier에 대해 이야기 해 봅시다.

PHPz
PHPz원래의
2023-04-11 09:10:37882검색

동시 코드를 작성할 때 데이터 경쟁과 경쟁 조건을 방지하기 위해 여러 고루틴과 상호 토큰 또는 잠금 간의 동기화를 보장해야 하는 경우가 많습니다. Go 언어는 chan 및 sync 패키지를 통해 이러한 동기화를 달성하기 위한 몇 가지 메커니즘을 제공하지만 때로는 유연성이 부족하여 더 고급 동기화 방법이 필요합니다.

A Barrier는 다음 작업을 계속하기 전에 고루틴 그룹이 동시에 작업을 완료할 때까지 기다리는 데 사용되는 동기화 프리미티브입니다. 이는 매우 일반적인 동기화 메커니즘입니다. Golang은 또한 "Barrier"라는 장벽을 구현하는 메커니즘을 제공합니다.

장벽의 원리는 고루틴 그룹을 두 단계로 나누는 것입니다. 첫 번째 단계는 각 고루틴이 자신의 작업을 완료한 후 중지되고 다른 고루틴이 완료될 때까지 기다립니다. 두 번째 단계는 모든 고루틴이 중지되고 완료될 때입니다. 서로 설정 신호를 받으면 모든 고루틴이 동시에 실행을 재개합니다.

Golang은 동기화 패키지에 "WaitGroup" 유형을 제공합니다. Add 메소드를 사용하여 대기 중인 고루틴 수를 추가합니다. Done 메소드는 각 고루틴이 작업을 완료한 후 WaitGroup에 대한 카운터를 줄이는 데 사용됩니다. 카운터가 0으로 떨어질 때까지 차단됩니다. 즉, 모든 고루틴이 다음 단계를 계속하기 전에 작업을 완료했습니다.

그러나 WaitGroup에는 고정된 수의 고루틴이 완료될 때까지만 기다릴 수 있다는 단점이 있습니다. 이때 Barrier를 사용하여 이 문제를 해결할 수 있습니다.

Barrier는 원하는 수의 고루틴과 함께 사용할 수 있으며 각 단계가 끝날 때 지정된 작업을 수행할 수 있습니다. 여기에는 일련의 작업이 완료되기를 기다리는 고루틴 수를 나타내는 카운터와 각 단계가 끝날 때 실행할 함수가 포함되어 있습니다.

Golang의 "대기 스레드 그룹"은 동기화 패키지의 "WaitGroup"을 사용하여 구현할 수 있습니다.

var wg sync.WaitGroup

func worker() {
    defer wg.Done()
    // 执行自己的任务
}

func main() {
    for i := 0; i < n; i++ {
        wg.Add(1)
        go worker()
    }
    // 等待所有线程完成
    wg.Wait()
}

이제 "Barrier"를 사용하여 변경 사항에 적용할 수 있는 goroutine의 예를 만듭니다.

package main

import "fmt"
import "sync"

func main() {
    b := sync.NewCond(&sync.Mutex{})
    done := make(chan bool)

    worker := func(id int) {
        defer func() {
            fmt.Printf("Worker %d done\n", id)
            done <- true
        }()
        fmt.Printf("Worker %d processing\n", id)
        b.L.Lock()
        b.Wait() // 等待阻塞直到b.Broadcast()被执行
        b.L.Unlock()
        fmt.Printf("Worker %d resumed\n", id)
    }

    go func() {
        for i := 0; i < 10; i++ {
            wg.Add(1)
            go worker(i)
        }
    }()

    go func() {
        for i := 0; i < 10; i++ {
            wg.Add(1)
            go worker(i)
        }
    }()

    go func() {
        wg.Wait()
        b.Broadcast()
    }()

    for i := 0; i < 20; i++ {
        <-done
    }
    fmt.Printf("All workers done\n")
}

이 예시는 두 단계로 나누어진 20개의 고루틴을 생성합니다. 첫 번째 단계는 각 고루틴이 자체 작업을 완료할 때까지 기다리고, 두 번째 단계는 작업을 실행하기 전에 모든 고루틴이 완료될 때까지 기다립니다.

두 개의 고루틴 그룹이 생성되면 고루틴 중 하나가 "대기"를 호출하고 모든 고루틴이 작업을 완료할 때까지 차단합니다. 다른 스레드가 작업을 완료하면 차단이 해제되고 다음 단계를 계속하기 위해 "Broadcast"를 사용하여 모든 고루틴에 신호가 전송됩니다.

간단히 말하면 Golang의 Barrier를 사용하면 동시 작업을 보다 고급 수준에서 동기화하고 코드를 더욱 강력하고 안정적으로 만들 수 있습니다.

위 내용은 golang의 Barrier에 대해 이야기 해 봅시다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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