2015-04-07 15 views
10

Farklı goroutinlerdeki farklı yapı üyelerine erişim güvenli midir?Hareket halindeki farklı yapıdaki üyelere erişmek güvenli midir?

package main 

type Apple struct { 
    color string 
    size uint 
} 

func main() { 
    apple := &Apple{} 
    go func() { 
     apple.color = "red" 
    }() 
    go func() { 
     apple.color = "green" 
    }() 
} 

Ama senkronizasyon her türlü olmadan farklı yapı üyelerine yazabilirsiniz:

Ben senkronize olmadan aynı değişkene yazma dangareous olduğunu anlıyoruz?

package main 

type Apple struct { 
    color string 
    size uint 
} 

func main() { 
    apple := &Apple{} 
    go func() { 
     apple.color = "red" 
    }() 
    go func() { 
     apple.size = 42 
    }() 
} 

Ya bunun için chan veya sync.Mutex kullanmalıyım?

cevap

11

Farklı iş parçacıklarından farklı değişkenlere erişmek güvenli olmalı ve yapı üyeleri farklı değişkenlerdir. Evet, güvenli olmalı. Ancak, hızlı olmayabilir. Yapı üyeleri gibi bellekte birbirine yakın olan değişkenler bir CPU önbellek satırı paylaşacaklardır. Bir önbellek çizgisi, bir CPU'nun (iyi, en güncel modellerin) kilitleyebileceği en küçük bellek parçasıdır. Bu, CPU-2'nin CPU-1'in farklı değişkenlere yazsalar bile o önbellek çizgisiyle bitene kadar yazmak için beklemesi gerektiği anlamına gelir.

Farklı iş parçacıklarından yapıya yazarken işaretçiyi yapıya değiştirmek güvenli DEĞİLDİR. Örneğinizde apple = &Apple{} numaralı üçüncü bir goroutine sahip olsaydınız, diğer threadlardaki diğer goroutinler, eski Apple'a veya yeni Apple'a yazabilir ve bunu bilmezdiniz.

+3

Paragraf 1 ve 3 harikadır; paragraf 2 konu dışı (endişe güvenliği olduğu için) ve kötü tavsiyeler (çünkü Go çok yüksek bir dil olduğu için varsayılan olarak en etkileyici kodu yazmalı ve gerektiğinde duruma göre optimize etmelisiniz). Genel olarak bu gerekçeyi uygulayarak değil. Bu goroutines'in bile farklı CPU'lar tarafından gerçekleştirileceğine dair bir garanti yoktur!). – weberc2

+0

@ weberc2 ile katılıyorum. Yanlış paylaşım bir endişe olsa da, soru bir muteksle veya onsuz 2 değişkenin değiştirilmesiyle ilgilidir. Önbellek çizgisi problemi, hangi cevabın doğru olduğuna bakılmaksızın mevcut olmalı ve çözüm, aynı olmayacaktır. – JimB

+0

@ weberc2: Komik, çünkü Go’yu sevdiğim sebeplerden biri, çünkü bu yüksek düzeyde bir dil değil. Çöp toplama ile C gibi çok derler. –

İlgili konular