Bir kanalı açık bırakmak uygun mudur?


161

Durumunu hiç kontrol etmiyorsam bir Go kanalını sonsuza kadar açık bırakmak (kanalı asla kapatmamak) uygun mudur? Bellek sızıntılarına neden olacak mı? Aşağıdaki kod uygun mu?

func (requestCh chan<- Request) GetResponse(data RequestData) Response {
    reply := make(chan Response)
    requestCh <- Request{data: data, replyCh: reply}
    return <-reply
}

Yanıtlar:


238

Bir Go kanalını sonsuza kadar açık bırakmak ve asla kapatmamak sorun değildir. Kanal artık kullanılmadığında çöp toplanacak.

Bir kanalın yalnızca alıcı bir kapanış arıyorsa kapatılması gerektiğini unutmayın. Kanalın kapatılması kanalda daha fazla verinin takip etmediğini belirten bir kontrol sinyalidir.

Tasarım Sorusu: Kanal Kapanışı


3
Bağlantının yanıtını kabul ettiğimden emin değilim. 2GB aralığında bellek sızıntısı yaşadım. Ben kapatır kapatmaz gayzer bir damlama oldu.
Richard

9
@Richard: Tüm diziyi dikkatlice okuyun. Bir arama yapmadıkça Go'nun gcyazarı ve gccgokanal closes denin yazarı gerekli değildir close. Bu yetkili bir tavsiye.
peterSO

6
@peterSO, olabilir ama ne gördüğümü biliyorum ve ben de bunu bildirdim, bu yüzden lütfen beni reddetme.
Richard

1
Arabelleklenmiş bir kanalınız varsa, ona mesaj eklemek bellek kullanmalıdır. Ancak kanalınız arabelleğe alınmazsa veya hiçbir şey eklenmezse bellek kullanımı artmaz.
metakeule


31

Evet, bir kanalı açık tutmakta bir sakınca yoktur. As halindeyken programlama dili kitap belirtildiği:

İşiniz bittiğinde her kanalı kapatmanıza gerek yoktur. Bir kanalı yalnızca alıcı goroutinlere tüm verilerin gönderildiğini söylemek önemli olduğunda kapatmak gerekir. Çöp toplayıcının ulaşılamaz olduğunu belirlediği bir kanal, kapalı olsun ya da olmasın kaynaklarını geri kazanacaktır. (Bunu açık dosyalar için kapatma işlemiyle karıştırmayın. İşiniz bittiğinde her dosyada Kapat yöntemini çağırmak önemlidir .)


7

Evet, kanalı açık bırakmak normaldir ve aslında tipiktir. Açık olan bir kanal, kanal nesnesine bir referans oluşturmaz ve dolayısıyla çöp toplanmasını engellemez.


1

" Go kanallarını kullanmanın genel bir ilkesi, bir kanalı alıcı tarafından kapatmamak ve kanalda birden fazla eşzamanlı gönderen varsa bir kanalı kapatmamaktır. "

Yukarıdaki yanıtta açıkça belirtildiği gibi, temizlik için işaretlendikten sonra her kanalın sonunda GCed edileceği açıktır, bu nedenle kanalı kapalı bırakmak bırakmak uygun olacaktır, tek fark, kanalın gcbirkaç döngüden sonra kullanılabilir olması olabilir açıkça kapatılmamış.

Aynı zamanda, aşağıdaki makaleler , bu ve bu Şekil, çeşitli yollar 1 durumunda bir kanalı kapatmak için: N, N-: 1 ya da E: N- (yayıncı: alıcılar)


-5

Go çöp toplanıyor, bu yüzden hiçbir şeyi 'serbest bırakmak' zorunda değilsiniz.

Kanalları kapatma olasılığı vardır, ancak çoğunlukla - close (kanal) - olarak goroutine (veya ana programa) o kanalda başka hiçbir şey gönderilmeyeceğini söyleyin.


8
AFAIK, çöp toplanmış bir dilde bile, bir programcı yönetilmeyen kaynakları, örneğin dosyaları, soketleri ve benzerlerini kapatmaktan hala sorumludur. Kanalı bir dosya gibi kapatmam gerekir mi?
Kluyg

3
@Kluyg Cevap hayır. İşletim sistemi kaynakları hakkında konuşuyorsunuz (hangi kanallar değil). Bir kaynağa ve dile bağlıdır, ancak genellikle GC'nin bunu yapmayacağı için değil, belirleyici olmadığı için işletim sistemi kaynaklarını elle kapatmanız önerilir. En yaygın ilgili gotcha çok fazla açık dosya hatasıdır. Dosyaları açmaya devam edersiniz ... GC'nin bunu yapmasını beklersiniz ... Belleğiniz bitmiyor (bu nedenle GC devreye girmiyor) ... İşletim sistemi düzeyinde dosya tanımlayıcılarınız bitiyor. İşletim Sistemi süreci öldürüyor :)
Pijusn

Neden bu kadar çok downvotes var bu süre boyunca doğru ve diğer kabul edilen cevaplar aynı
bildiriyor karıştı
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.