> 백엔드 개발 > Golang > Golang 동시 프로그래밍에서 고루틴의 동기화 및 상호 배제 메커니즘에 대한 자세한 설명

Golang 동시 프로그래밍에서 고루틴의 동기화 및 상호 배제 메커니즘에 대한 자세한 설명

PHPz
풀어 주다: 2023-07-20 11:25:10
원래의
990명이 탐색했습니다.

Golang 동시 프로그래밍에서 고루틴의 동기화 및 상호 배제 메커니즘에 대한 자세한 설명

멀티 코어 프로세서의 인기와 컴퓨터 성능의 지속적인 개선으로 인해 병렬 컴퓨팅을 위해 다중 프로세서 코어를 최대한 활용하는 방법이 중요해졌습니다. 개발자가 직면한 문제. 동시 프로그래밍은 이러한 문제를 해결하는 핵심 기술 중 하나입니다. Golang에서는 동시 프로그래밍을 구현하기 위해 고루틴과 채널이 널리 사용됩니다. 그중 고루틴은 높은 동시성 작업 처리를 달성할 수 있는 경량 스레드입니다. 여러 고루틴 간의 올바른 협력을 보장하기 위해서는 동기화 및 상호 배제 메커니즘이 중요한 역할을 합니다.

1. 고루틴의 기본 개념
Golang에서 고루틴은 다른 고루틴과 동시에 실행할 수 있는 경량 스레드입니다. 고루틴은 기존 스레드보다 생성 및 삭제하는 데 드는 리소스가 적고 시스템 리소스를 보다 효율적으로 활용할 수 있습니다.

고루틴은 "go"라는 키워드로 생성됩니다. 샘플 코드는 다음과 같습니다.

package main

import (
    "fmt"
    "time"
)

func task1() {
    for i := 0; i < 5; i++ {
        fmt.Println("Task 1:", i)
        time.Sleep(time.Millisecond * 500)
    }
}

func task2() {
    for i := 0; i < 5; i++ {
        fmt.Println("Task 2:", i)
        time.Sleep(time.Millisecond * 500)
    }
}

func main() {
    go task1()
    go task2()

    time.Sleep(time.Millisecond * 3000)
}
로그인 후 복사

위 코드에서는 "go"라는 키워드를 통해 두 개의 고루틴을 생성하고 task1()task2() 함수를 실행합니다. 각기. main() 함수에서 time.Sleep() 함수를 통해 3초 동안 기다려 고루틴이 실행을 완료하는 데 충분한 시간을 갖도록 합니다. task1()task2()函数。在main()函数中,通过time.Sleep()函数等待3秒钟,保证Goroutines有足够的时间执行完毕。

二、Goroutines的同步与互斥机制
在实际的并发编程中,多个Goroutines可能需要共享某些资源。这时候就需要通过同步与互斥机制来确保资源的正确访问。

  1. 同步
    在Golang中,常用的同步机制有WaitGroup、Mutex和RWMutex。

1.1 WaitGroup
WaitGroup用于等待一组Goroutines的执行完成。它的功能类似于Java中的CountDownLatch。示例代码如下:

package main

import (
    "fmt"
    "sync"
    "time"
)

func task(i int, wg *sync.WaitGroup) {
    defer wg.Done()

    fmt.Println("Task", i)
    time.Sleep(time.Millisecond * 500)
}

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 5; i++ {
        wg.Add(1)
        go task(i, &wg)
    }

    wg.Wait()
    fmt.Println("All tasks finished")
}
로그인 후 복사

在上述代码中,通过sync.WaitGroup创建了一个等待组wg。在每个Goroutine的执行前调用wg.Add(1)将等待组计数器加1,表示有一个任务需要等待。在每个Goroutine执行完毕后调用wg.Done()将等待组计数器减1,表示一个任务已完成。最后,通过wg.Wait()等待所有任务执行完成。

1.2 Mutex
Mutex是一种互斥锁,用于保护共享资源在同一时间只能被一个Goroutine访问。示例代码如下:

package main

import (
    "fmt"
    "sync"
    "time"
)

var count int
var mutex sync.Mutex

func task(i int, wg *sync.WaitGroup) {
    defer wg.Done()

    mutex.Lock()
    defer mutex.Unlock()

    count++
    fmt.Println("Task", i, "count:", count)
    time.Sleep(time.Millisecond * 500)

    mutex.Lock()
    defer mutex.Unlock()

    count--
}

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 5; i++ {
        wg.Add(1)
        go task(i, &wg)
    }

    wg.Wait()
    fmt.Println("All tasks finished")
}
로그인 후 복사

在上述代码中,通过sync.Mutex创建了一个互斥锁mutex。在每个Goroutine中,通过调用mutex.Lock()mutex.Unlock()的配对来保护共享资源的访问。在实际的应用中,可以将需要保护的共享资源存放在结构体中,通过结构体中的互斥锁来控制对共享资源的访问。

  1. 互斥
    除了同步外,有时候还需要通过互斥来保证某段代码在同一时间只能被一个Goroutine执行。在Golang中,常用的互斥机制有Once和Mutex。

2.1 Once
Once用于保证某段代码在程序运行期间只会执行一次。示例代码如下:

package main

import (
    "fmt"
    "sync"
)

var once sync.Once

func task() {
    fmt.Println("Task executed")
}

func main() {
    for i := 0; i < 5; i++ {
        once.Do(task)
    }
}
로그인 후 복사

在上述代码中,通过sync.Once创建了一个Once对象once。在每个Goroutine中,通过调用once.Do(task)来保证task()函数在整个程序运行期间只会执行一次。

2.2 Mutex
Mutex也可以用来实现互斥。示例代码如下:

package main

import (
    "fmt"
    "sync"
    "time"
)

var count int
var mutex sync.Mutex

func task(i int, wg *sync.WaitGroup) {
    defer wg.Done()

    mutex.Lock()
    defer mutex.Unlock()

    fmt.Println("Task", i)
    time.Sleep(time.Millisecond * 500)
}

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 5; i++ {
        wg.Add(1)
        go task(i, &wg)
    }

    wg.Wait()
    fmt.Println("All tasks finished")
}
로그인 후 복사

在上述代码中,通过调用mutex.Lock()mutex.Unlock()来保证在同一时间只能有一个Goroutine执行task()

2. 고루틴의 동기화 및 상호 배제 메커니즘

실제 동시 프로그래밍에서는 여러 고루틴이 특정 리소스를 공유해야 할 수도 있습니다. 이때 리소스에 대한 올바른 액세스를 보장하려면 동기화 및 상호 배제 메커니즘이 필요합니다.

  1. 동기화Golang에서 일반적으로 사용되는 동기화 메커니즘에는 WaitGroup, Mutex 및 RWMutex가 있습니다.
🎜1.1 WaitGroup🎜WaitGroup은 고루틴 그룹의 실행이 완료되기를 기다리는 데 사용됩니다. 해당 기능은 Java의 CountDownLatch와 유사합니다. 샘플 코드는 다음과 같습니다. 🎜rrreee🎜위 코드에서는 sync.WaitGroup을 통해 대기 그룹 wg가 생성됩니다. 각 고루틴이 실행되기 전에 wg.Add(1)를 호출하여 대기 그룹 카운터를 1씩 증가시켜 대기해야 하는 작업이 있음을 나타냅니다. 각 고루틴이 실행된 후 wg.Done()을 호출하여 대기 그룹 카운터를 1씩 줄여 작업이 완료되었음을 나타냅니다. 마지막으로 wg.Wait()를 통해 모든 작업이 완료될 때까지 기다립니다. 🎜🎜1.2 Mutex🎜Mutex는 동시에 하나의 고루틴에서만 액세스할 수 있는 공유 리소스를 보호하는 데 사용되는 뮤텍스 잠금입니다. 샘플 코드는 다음과 같습니다. 🎜rrreee🎜위 코드에서는 sync.Mutex를 통해 뮤텍스 잠금 mutex가 생성됩니다. 각 고루틴에서는 mutex.Lock()mutex.Unlock() 쌍을 호출하여 공유 리소스에 대한 액세스를 보호합니다. 실제 애플리케이션에서는 보호해야 할 공유 자원을 구조체에 저장하고, 구조체의 mutex lock을 통해 공유 리소스에 대한 접근을 제어할 수 있다. 🎜
  1. 상호 배제🎜동기화 외에도 때로는 특정 코드 조각이 동시에 하나의 고루틴에서만 실행될 수 있도록 하기 위해 상호 배제가 필요할 때도 있습니다. Golang에서 일반적으로 사용되는 상호 배제 메커니즘에는 Once와 Mutex가 있습니다.
🎜2.1 Once🎜Once는 프로그램 실행 중에 특정 코드가 한 번만 실행되도록 하는 데 사용됩니다. 샘플 코드는 다음과 같습니다. 🎜rrreee🎜위 코드에서는 sync.Once를 통해 Once 객체 once가 생성됩니다. 각 고루틴에서 once.Do(task)를 호출하면 task() 함수가 전체 프로그램 실행 시간 동안 한 번만 실행됩니다. 🎜🎜2.2 Mutex🎜Mutex를 사용하여 상호 배제를 구현할 수도 있습니다. 샘플 코드는 다음과 같습니다. 🎜rrreee🎜위 코드에서 mutex.Lock()mutex.Unlock()을 호출하여 하나의 고루틴만 허용되도록 합니다. 동시에 task() 함수를 실행하고 공유 리소스에 액세스합니다. 🎜🎜요약🎜 이번 글의 소개를 통해 Golang 동시 프로그래밍에서 고루틴의 동기화 및 상호 배제 메커니즘에 대해 알아보았습니다. 실제 애플리케이션에서 동기화 및 상호 배제 메커니즘은 여러 고루틴 간의 올바른 협업을 보장하는 핵심입니다. WaitGroup, Mutex 및 RWMutex와 같은 동기화 및 상호 배제 메커니즘을 적절하게 사용하면 공유 리소스에 대한 올바른 액세스를 보장하여 효율적인 동시 프로그래밍을 달성할 수 있습니다. 🎜

위 내용은 Golang 동시 프로그래밍에서 고루틴의 동기화 및 상호 배제 메커니즘에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿