Apakah boleh membiarkan saluran terbuka?

161

Apakah boleh meninggalkan saluran Go selamanya (tidak pernah menutup saluran) jika saya tidak pernah memeriksa kondisinya? Apakah ini akan menyebabkan kebocoran memori? Apakah kode berikut OK?

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

Jawaban:

238

Boleh saja membiarkan saluran Go tetap terbuka selamanya dan tidak pernah menutupnya. Ketika saluran tidak lagi digunakan, itu akan menjadi sampah yang dikumpulkan.

Perhatikan bahwa Anda hanya perlu menutup saluran jika penerima mencari penutupan. Menutup saluran adalah sinyal kontrol pada saluran yang menunjukkan bahwa tidak ada lagi data yang mengikuti.

Pertanyaan Desain: Penutupan Saluran

peterSO
sumber
3
Saya tidak yakin saya setuju dengan respons tautan. Saya mengalami kebocoran memori pada kisaran 2GB. Segera setelah saya menambahkan tutupnya geyser menjadi menetes.
Richard
9
@ Richard: Baca seluruh utas dengan cermat. Penulis Go gcdan penulis gccgosay channel closes tidak diperlukan, kecuali jika Anda mencari a close. Itu saran resmi.
peterSO
6
@ PeterSO, itu mungkin tapi saya tahu apa yang saya lihat dan itulah yang saya laporkan jadi tolong jangan abaikan saya.
Richard
1
Nah jika Anda memiliki saluran buffer, menambahkan pesan ke dalamnya harus menggunakan memori. Namun jika saluran Anda tidak disangga atau tidak ada yang ditambahkan, penggunaan memori tidak akan bertambah.
metakeule
Lalu bagaimana dengan ini: groups.google.com/forum/#!topic/golang-nuts/bfuwmhbZHYw ?
Kamil Dziedzic
31

Ya, tidak apa-apa untuk menjaga saluran tetap terbuka. Seperti yang dinyatakan buku bahasa pemrograman go :

Anda tidak perlu menutup setiap saluran setelah selesai. Itu hanya perlu untuk menutup saluran ketika penting untuk memberi tahu goroutine penerima bahwa semua data telah dikirim. Sebuah saluran yang oleh para pengumpul sampah dianggap tidak dapat dijangkau akan membuat sumber dayanya diambil kembali baik itu ditutup atau tidak. (Jangan bingung dengan operasi tutup untuk file terbuka. Penting untuk memanggil metode Tutup pada setiap file ketika Anda selesai menggunakannya.)

cizixs
sumber
7

Ya, tidak apa-apa untuk membiarkan saluran tetap terbuka, dan sebenarnya itu tipikal. Saluran yang terbuka bukan merupakan referensi ke objek saluran, dan karenanya tidak mencegahnya dari pengumpulan sampah.

Sonia
sumber
1

" Salah satu prinsip umum menggunakan saluran Go adalah jangan tutup saluran dari sisi penerima dan jangan tutup saluran jika saluran memiliki beberapa pengirim bersamaan. "

Seperti disebutkan dengan jelas dalam jawaban di atas bahwa setiap saluran akan menjadi GCed pada akhirnya setelah ditandai untuk pembersihan, jadi tidak apa-apa untuk membiarkan saluran tidak ditutup, satu-satunya perbedaan yang akan terjadi adalah bahwa saluran tersebut akan tersedia untuk gcsetelah beberapa siklus mungkin jika tidak ditutup secara eksplisit.

Juga artikel berikut ini dan ini menunjukkan berbagai cara untuk menutup saluran jika 1: N, N: 1 atau M: N (pengirim: penerima)

Abhishek Srivastava
sumber
-5

Go adalah sampah yang dikumpulkan, jadi Anda tidak perlu 'membebaskan' apa pun.

Ada kemungkinan untuk menutup saluran, tetapi sebagian besar digunakan sebagai - tutup (saluran) - beri tahu goroutine (atau program utama) bahwa tidak ada lagi yang akan dikirim pada saluran itu.

Łukasz Gruner
sumber
8
AFAIK bahkan dalam bahasa sampah yang dikumpulkan seorang programmer masih bertanggung jawab untuk membebaskan sumber daya yang tidak dikelola, misalnya menutup file, soket dan sebagainya. Apakah saya perlu menutup saluran seperti file?
Kluyg
3
@ Kluyg Jawabannya adalah tidak. Anda berbicara tentang sumber daya OS (saluran mana yang tidak). Itu tergantung pada sumber daya dan bahasa, tetapi biasanya disarankan untuk menutup sumber daya OS secara manual bukan karena GC tidak akan melakukannya tetapi karena itu tidak deterministik. Gotcha terkait yang paling umum adalah terlalu banyak kesalahan pada file terbuka . Anda terus membuka file ... Anda berharap GC melakukannya ... Anda tidak kehabisan memori (oleh karena itu GC tidak masuk) ... Anda kehabisan deskriptor file di tingkat OS. OS membunuh prosesnya :)
Pijusn
Saya bingung mengapa ini mendapat banyak downvotes sementara itu benar sepanjang waktu dan menyatakan sama dengan jawaban yang diterima lainnya ...
eja