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:
개선된 구현은 다음과 같습니다. 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는 명시적인 동기화 없이 스레드 안전성을 어떻게 달성합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!