Golang Race Condition

200 views
Skip to first unread message

omer.furk...@gmail.com

unread,
May 4, 2022, 5:58:52 AM5/4/22
to Golang Türkiye
Merhaba bir projem mevcut ve birden fazla go routine mevcut. Uygulamam bazen crash oluyor. 

fatal error: concurrent map read and map write

Race condition tespit etmek için Go nun -race flagını kullanmaya çalıştım daha iyi sonuç alıp problemleri tespit etmek için ama build sonrası böyle bir hata alıyorum

race: limit on 8128 simultaneously alive goroutines is exceeded, dying

Bu problemi nasıl geçebilirim ? Bir fikri olan var mı acaba veya go da race condition tespit etmenin farklı yolları var mı ? 

Teşekkürler.


cengizhan sarı

unread,
May 5, 2022, 3:49:59 AM5/5/22
to gola...@googlegroups.com
Merhaba, 

Birden fazla go routine'iniz aynı anda aynı değişkene erişmeye çalışıyor sanırım. Mutex yardımı ile bu problemi giderebilirsiniz.

Saygılarımla, iyi çalışmalar.

omer.furk...@gmail.com <omer.furk...@gmail.com>, 4 May 2022 Çar, 12:58 tarihinde şunu yazdı:
--
Bu iletiyi Google Grupları'ndaki "Golang Türkiye" grubuna abone olduğunuz için aldınız.
Bu grubun aboneliğinden çıkmak ve bu gruptan artık e-posta almamak için golang-tr+...@googlegroups.com adresine e-posta gönderin.
Bu tartışmayı web'de görüntülemek için https://groups.google.com/d/msgid/golang-tr/c429e8ec-5c7d-4ca2-89b5-13bebd72a679n%40googlegroups.com adresini ziyaret edin.

Sean Tolstoyevski

unread,
May 7, 2022, 6:48:17 AM5/7/22
to Golang Türkiye
Selamlar,
Stack'ten donen veriler (panic'in asagisindakiler), hatanin nerede oldugunu gosterecektir.
Eger halen dogru bir cikti alamiyorsaniz farkli platformlarda derleme yapmayi deneyebilirsiniz. Bu tip ozellikler, kernel'in ne kadar ozellik sagladigina bagli biraz. Muhtemelen Linux'ta daha detayli bir cikti alacaksinizdir.

Emre – Software Developer 👨‍🦯


cengizhan sarı <cengizha...@gmail.com>, 5 May 2022 Per, 10:49 tarihinde şunu yazdı:

selam

unread,
May 9, 2022, 3:54:26 AM5/9/22
to gola...@googlegroups.com
"fatal error: concurrent map read and map write" Burada aslında size
neden crash olduğunu söylüyor, bir map kullanmışsın ancak iki farklı
goroutine aynı anda okuma ve yazma yapmaya çalışıyor.

bunu bir kitabı okurken birisinin gelip okuduğunuz sayfada yazı
yazmaya başkadığını hayal edin, görünmez bir el sayfada cümleleri
değiştiriyor, okumaya başladığınız cümle değişmeye başlarsa başı ile
sonu arasında sizin kafasınızda bir tutarsızlık olacaktır. bu durumda
golang sizi uyarıyor. kafan karışacak böyle şeyler yapma diyor. yine
belki kitabın okuduğunuz yeri değilde okumadığınız yerlerini
değiştirdiğini düşünün, bir kısmını okudunuz, son kısmı değiştirildi,
dolayısı ile kitaba başlarken casus romanı idi, bitişi tarih kitabına
döndü. tutarsızlık diz boyu olur.

nasıl engellersiniz?.

1 - map'i bir struct içerisine yerleştirmek birde sync.Mutex eklemek,
map'e eriştiğiniz her yerde de bu struct'ın func'ların üzerinden
erişmek,

get, set methodları yazıp içerisinde lock, unlock etmek, burada başka
bir sıkıntı çıkıyor özellikle de defer kullanımı ile ilgili, deferred
func'lar hemen çalışmadığı için scheduler üzerine yerleştiriliyor,
func çalışması biter bitmez değilde scheduler ne zaman uygun görürse o
zaman çalıştırıyor, bu map'e erişimde performans düşmesine neden
oluyor zira unlock hemen çalışmadan map üzerinde bir işlem daha
yapmaya çalışılıyor ve tekrar lock etmeden önce unlock'ı
bekliyorsunuz. deferred func kullanmadan yazarsanız daha performanslı
olur.

2 - sync paketinden sync.Map kullanmak, performansı daha yüksek
(yukarıdaki implementasyona göre), sync.map'de ki problem ise
make(map[int]string) gibi bir type tanımlamasının olmaması, keyler ve
value'lar birer interface olarak tanımlı, bu nedenle value'ları
kullanırken type cast' yapmak zorunda kalıyorsunuz.

3. iki farklı map tutmak, diyelim ki, map'iniz oldukça büyük, (100mb
yer kaplayan map var elinizde) ve değişim oranı düşük, (bir yerden
birdata elecek ve o datayı map'e koyacaksınız.
1 yeni bir map oluşturun make ile,
2 eski map'deki verileri bu yeni map'e yerleştirin.
3 güncellemeyi yeni map'de yapın.

eski map'i taşıyan değişkene yeni map'i verin.

atamalar atomic olduğundan sorun yaşamazsınız ancak yeni map'e eski
verileri koyma işlemi bitene kadar memory de çok fazla işlem
yapılacağı için performans düşer. memory kullanımı artar. bu
yukarıdaki durumu belki günde bir iki defa güncellenecek map'ler için
kullanabilirsiniz tabii memory'niz varsa ölçeklenebilirliği çok
düşünmüyorsanız.

mutex ve semafor nedir, ne zaman gerekir gibi konuları okuyun.
bilgileriniz tazelensin.

bonus okuma: https://dave.cheney.net/2018/05/29/how-the-go-runtime-implements-maps-efficiently-without-generics
Bonus arama: how map's works for different objects with same hash
> --
> Bu iletiyi Google Grupları'ndaki "Golang Türkiye" grubuna abone olduğunuz için aldınız.
> Bu grubun aboneliğinden çıkmak ve bu gruptan artık e-posta almamak için golang-tr+...@googlegroups.com adresine e-posta gönderin.
> Bu tartışmayı web'de görüntülemek için https://groups.google.com/d/msgid/golang-tr/c429e8ec-5c7d-4ca2-89b5-13bebd72a679n%40googlegroups.com adresini ziyaret edin.



--
Saygılar && İyi Çalışmalar
Timu EREN ( a.k.a selam )

Ömer Furkan

unread,
May 9, 2022, 4:27:35 PM5/9/22
to gola...@googlegroups.com
Merhabalar cevaplarınız için herkese çok ayrı teşekkür ederim.  sela...@gmail.com bu aydınlatıcı bilgiler için çok ayrı teşekkür ederim.. Burayı biraz karalamak istiyorum affınıza sığınarak, 

Map yapım bu şekilde olay characters isimli mapde gerçekleşiyor. Değindiğiniz gibi mutexleri aktif ve yerinde kullanmaya çalışıyorum. 

Proje yapı itibariyle biraz geniş ve büyük olmakla beraber bizim elimizden çıkan bir şey değil. Bu yüzden günlerdir saç baş yolduk. Bunu nasıl debug edebileceğimiz hakkında da bir fikrimiz yok çünkü tam olarak ne sebep oluyor fikrimiz bile yok sadece panic çıktısı ve işaret ettiği kısım bu maplere erişen her fonksiyon mutex ile kilitlenip açılıyor. 

1.png


Uygulamamın crash olduğu yerlerden biri bu kısım. Burada mapimi locklayıp verilerden yeni bir dizi oluşturuyorum sonrasında unlock yapıyorum resimde ki iki fonksiyonu da denedim benim için değişen bir şey olmadı.


2.png


Hatamın çıktısı ise bu şekilde


3.png




selam <sela...@gmail.com>, 9 May 2022 Pzt, 10:54 tarihinde şunu yazdı:
--
Bu e-postayı Google Grupları'ndaki "Golang Türkiye" adlı gruba abone olduğunuz için aldınız.

Bu grubun aboneliğinden çıkmak ve bu gruptan artık e-posta almamak için golang-tr+...@googlegroups.com adresine e-posta gönderin.

selam

unread,
May 10, 2022, 8:20:55 AM5/10/22
to gola...@googlegroups.com
ekran görüntüsü atmak yerine play.golang gibi servisleri kullanırsanız gelen kutumuz sevinir.


yazan bir yer var değil mi? orayı bul.




Reply all
Reply to author
Forward
0 new messages