> 백엔드 개발 > Golang > Go는 명시적인 동기화 없이 스레드 안전성을 어떻게 달성합니까?

Go는 명시적인 동기화 없이 스레드 안전성을 어떻게 달성합니까?

Barbara Streisand
풀어 주다: 2024-12-18 10:30:10
원래의
360명이 탐색했습니다.

How Does Go Achieve Thread Safety Without Explicit Synchronization?

Go의 스레드 안전성: 동기화의 대안

프로그래밍 영역에서 스레드 안전성은 변수에 동시에 액세스할 수 있도록 보장합니다. 데이터 불일치를 일으키지 않고 여러 스레드를 사용합니다. Go에서는 동기화 키워드를 사용하여 Java에서 볼 수 있는 동기화 개념이 명시적으로 적용되지 않고 오히려 다른 메커니즘을 통해 해결됩니다.

Go는 '메모리를 공유하는 방식'이 아닌 '공유를 통한 통신' 방식을 옹호합니다. 소통해요." 이 패러다임은 공유 변수에 직접 액세스하는 대신 채널을 통해 고루틴 간 정보 교환을 권장합니다.

Mutex: A Classical Solution

그러나 변수를 잠그고 공유하는 시나리오에서는 불가피하게 Go는 뮤텍스를 제공합니다. 다음 예를 고려하십시오.

import (
    "sync"
)

var (
    mu        sync.Mutex
    protectMe int
)

func getMe() int {
    mu.Lock()
    me := protectMe
    mu.Unlock()
    return me
}

func setMe(me int) {
    mu.Lock()
    protectMe = me
    mu.Unlock()
}
로그인 후 복사

이 코드에서 변수 protectedMe는 mu라는 뮤텍스를 사용하여 보호됩니다. getMe 및 setMe 함수는 이 뮤텍스를 활용하여 protectedMe에 대한 안전한 동시 액세스를 보장합니다.

개선 사항 및 대안

위 솔루션은 기능적이지만 성능을 향상하는 여러 가지 방법이 있습니다. it:

  • sync.RWMutex를 사용하여 각각을 차단하지 않고 동시 읽기를 허용합니다. 기타.
  • 오류나 패닉이 발생하더라도 뮤텍스가 해제되도록 지연 잠금 해제를 도입하세요.
  • 캡슐화 및 사용 편의성을 위해 구조체 내부에 뮤텍스와 보호된 데이터를 삽입하세요.

개선된 구현은 다음과 같습니다. this:

type Me struct {
    sync.RWMutex
    me int
}

func (m *Me) Get() int {
    m.RLock()
    defer m.RUnlock()
    return m.me
}

func (m *Me) Set(me int) {
    m.Lock()
    m.me = me
    m.Unlock()
}

var me = &Me{}
로그인 후 복사

원자적 연산

단일 정수를 보호하기 위해 Go는 sync/atomic 패키지를 통해 원자적 연산을 제공합니다. 다음 코드를 고려하십시오.

import "sync/atomic"

var protectMe int32

func getMe() int32 {
    return atomic.LoadInt32(&protectMe)
}

func setMe(me int32) {
    atomic.StoreInt32(&protectMe, me)
}
로그인 후 복사

원자적 연산은 단일 값에 대한 스레드로부터 안전한 액세스를 보장하며 특정 상황에서는 뮤텍스보다 더 나은 성능을 제공할 수 있습니다.

공유를 통한 통신

앞서 언급했듯이 Go에서는 채널을 통한 소통이 권장됩니다. 두 개의 고루틴이 있다고 상상해 보세요. 하나는 상태를 설정하고 다른 하나는 상태를 읽는 것입니다. 공유 변수를 사용하고 이에 대한 액세스를 동기화하는 대신 채널을 사용하여 setter에서 리더로 상태를 보낼 수 있습니다.

import "sync"

var c chan int

func init() {
    c = make(chan int)
}

func getMe() int {
    return <-c
}

func setMe(me int) {
    c <- me
}
로그인 후 복사

이 접근 방식은 공유 변수 및 동기화의 필요성을 없애고 코드를 작성하고 동시 액세스에 대해 본질적으로 안전하도록 만듭니다.

추가 리소스

  • [Go Blog: 소통으로 추억 공유](링크)
  • [다른 스레드에서 값 읽기](링크)

위 내용은 Go는 명시적인 동기화 없이 스레드 안전성을 어떻게 달성합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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