2012-12-17 15 views
13

Bazı arkaplanlar:
Sızıntı-kova gibi bir şey için kullanılan, go rutinleri arasında paylaşılan bir karşı değişkene ihtiyacım var. Etkin Go, eşzamanlı bölümde sızan bir kepçe örneği olduğunu biliyorum, ancak izlemem gereken numara çok büyük olabilir ve bunu izlemek için bir kanaldaki öğe sayısını kullanmanın etkisiz olduğunu hissediyorum. Bu yüzden numarayı izlemek için farklı rutinler arasında paylaşılan bir değişken kullanmayı düşünüyorum.X86'da Go atomic'te artış operatörleri mi bulunuyor?

Açık yapılandırma olmadan, tüm gidilen yordamların bir iş parçacığına eşlendiğini anlıyorum. Ancak, çok çekirdekli bir bilgisayarda programa birden fazla iş parçacığı atarsam, operatörleri atomik artırır mı? Farklı makinelerde farklı veri türleri (int32, float32, vb.) Için hepsi aynı mı (x86_32, x86_64, arm)?

daha somut olmak gerekirse, ne başka rutin bir rutin içinde counter += 1000 ve counter -= 512 var ve iki rutinleri iki iş parçacığı çalışıyor olması bir şey olursa? İplik güvenliği konusunda endişelenmem gerekir mi? counter'da kilitler koyayım mı?

cevap

16

Hayır, artış asla atomik olarak kabul edilmemelidir. Atomik ekleme fonksiyonlarını veya muteks kullanın. Başka bir muteks olmadan atomic.AddInt32(counter, -512) yaptı ise

import "sync/atomic" 
var counter = new(int32) 

Bir goroutine atomic.AddInt32(counter, 1000) yapabilirdi:

varsayalım.

Bunun yerine bir muteksi kullanmak istiyorsanız:

import "sync" 
var counter int32 
var mutex sync.Mutex 

func Add(x int32) { 
    mutex.Lock() 
    defer mutex.Unlock() 
    counter += x 
} 
+0

Vay. Teşekkürler! Senkronizasyon/atomik olduğunu fark etmedim. Bu işleri daha kolay hale getirir! –