Rumah > Artikel > pembangunan bahagian belakang > golang chan tidak boleh menghalang
Saluran dalam bahasa Go ialah struktur data yang sangat berguna Ia boleh merealisasikan perkongsian data dan penyegerakan dalam pengaturcaraan serentak, dan ia sangat cekap. Walau bagaimanapun, terdapat satu perkara yang memerlukan perhatian khusus apabila menggunakan saluran, dan ia juga merupakan kesilapan yang sering dilakukan oleh ramai pemula bahasa Go, iaitu, chan tidak boleh menyekat.
Dalam bahasa Go, penghantaran data dan penyegerakan antara berbilang goroutine boleh dicapai melalui saluran, dengan itu mengelakkan kunci penyegerakan yang rumit dan masalah kebuntuan yang tidak dapat dielakkan. Apabila kami menggunakan saluran untuk menghantar dan menerima data antara dua atau lebih goroutine, kami sering menggunakan kod berikut:
ch := make(chan int) go func() { ch <- 1 }() value := <-ch fmt.Println(value)
Dalam kod ini, kami mencipta saluran jenis int, dan integer 1 dihantar ke saluran dalam goroutine baru. Kemudian, panggil <-ch
dalam goroutine utama untuk menerima data dalam saluran dan mencetaknya. Contoh ini mudah, tetapi ia menunjukkan penggunaan saluran untuk menyegerakkan data antara dua goroutin.
Dalam kod di atas, kami mungkin mendapati saluran itu tidak ditutup secara eksplisit dan ia tidak dicache. Jadi, dalam kes ini, apa yang berlaku apabila kita membaca saluran yang tidak ditutup dan tidak dicache?
Dalam kes ini, jika saluran kosong, maka kita akan menyekat apabila membacanya sehingga goroutine menulis nilai baru atau menutup saluran. Walau bagaimanapun, jika saluran kekal kosong, program kami akan disekat secara kekal. Ini adalah situasi yang sangat berbahaya dan sering membawa kepada kebuntuan dan masalah lain dalam program dalam aplikasi praktikal.
Jadi bagaimana kita boleh mengelakkan perkara ini? Ia sebenarnya sangat mudah, kita hanya perlu memastikan bahawa saluran tidak menyekat apabila menggunakannya. Selagi kami boleh memastikan saluran tidak akan kekal kosong semasa menggunakannya, kami boleh mengelakkan masalah sekatan.
Cara biasa ialah menentukan sama ada status saluran berikut kosong sebelum goroutine menulis nilai, atau memberinya kapasiti semasa menyimpan cache saluran untuk memastikan penulisan nilai tidak akan menyebabkan penyekatan. Sebagai contoh, dalam contoh berikut kami menggunakan saluran cache:
ch := make(chan int, 1) ch <- 1 value := <-ch fmt.Println(value)
Di sini, kami menentukan kapasiti 1 semasa mencipta saluran, jadi selepas menulis nilai, walaupun kami tidak membaca nilai ini dengan segera, program masih tidak akan disekat. Ini mengelakkan masalah yang disebutkan di atas.
Selain menggunakan saluran cache untuk mengelakkan sekatan, kami juga boleh menggunakan penyata terpilih untuk mengendalikan operasi baca dan tulis saluran. Pernyataan pilih boleh memantau berbilang saluran pada masa yang sama Setelah salah satu saluran menerima nilai, operasi yang sepadan akan dilakukan serta-merta. Contohnya, contoh berikut:
ch := make(chan int) timer := time.NewTicker(time.Second) select { case ch <- 1: fmt.Println("value sent") case <-timer.C: fmt.Println("timeout") }
Di sini, kami mencipta Ticker baharu yang dicetuskan sekali setiap saat. Kemudian kita mendengar dua saluran dalam pernyataan pilih Jika ch boleh ditulis, "nilai dihantar" adalah output, jika tidak "masa tamat" adalah output selepas satu saat.
Ringkasnya, walaupun saluran adalah struktur data yang sangat berguna, penjagaan khas perlu diambil semasa menggunakannya untuk mengelakkan sekatan. Selagi kami boleh memastikan saluran tidak disekat apabila menggunakannya, kami boleh menggunakan sepenuhnya alat ini untuk mencapai pengaturcaraan serentak yang cekap.
Atas ialah kandungan terperinci golang chan tidak boleh menghalang. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!