𝗞𝘂𝗮𝘀𝗮𝗶 𝗚𝗼 𝗖𝗼𝗻𝗰𝘂𝗿𝗿𝗲𝗻𝗰𝘆 𝗱𝗲𝗻𝗴𝗮𝗻 𝗖𝗵𝗮𝗻𝗻𝗲𝗹𝘀
Saya pernah membina pipeline pemprosesan imej dalam Go.
Saya menggunakan goroutines untuk setiap langkah. Saya menghubungkannya dengan channels. Saya tekan run.
Program tersebut membeku. Penggunaan memori meningkat. Kemudian ia mati. Tiada ralat yang muncul. Hanya kesunyian.
Saya membazirkan masa berjam-jam menyahpepijat (debugging) scheduler yang rosak. Saya silap. Saya tidak faham bagaimana channels berfungsi.
Berikut adalah tiga peraturan untuk mengelakkan program Go anda daripada tergantung (hanging).
- Nil channels adalah lubang hitam Satu nil channel akan menyekat (block) selama-lamanya. Jika anda menghantar atau menerima pada nil channel, goroutine tersebut akan tersangkut.
- Sentiasa mulakan (initialize) channels anda dengan
make. - Gunakan semakan nil jika anda tidak pasti.
- Peraturan penutupan mengelakkan panic Menutup channel adalah kekal.
- Hanya penghantar (sender) sahaja yang patut menutup channel.
- Menghantar data ke channel yang telah ditutup akan menyebabkan panic.
- Gunakan nilai pulangan kedua untuk menyemak jika channel telah ditutup:
v, ok := <-ch. - Jika
okadalah false, channel tersebut telah ditutup.
- Gunakan arah channel untuk keselamatan Go membolehkan anda menentukan sama ada channel adalah untuk menghantar atau menerima.
chan<- intbermaksud anda hanya boleh menghantar data.<-chan intbermaksud anda hanya boleh menerima data.- Ini memaksa pengkompil (compiler) untuk mengesan kesilapan sebelum anda menjalankan kod anda.
Cara membina pipeline yang bersih:
- Gunakan
defer closeuntuk memastikan channel ditutup tepat sekali. - Gunakan
rangeuntuk melakukan gelung (loop) pada channels. Ini akan berhenti secara automatik apabila channel ditutup. - Tetapkan jenis arah (direction types) pada fungsi anda untuk mencipta kontrak yang ketat.
Apabila anda mengikut corak ini, anda dapat mengelakkan kebocoran (leaks) dan panic. Anda membina sistem yang mudah diuji dan teguh (robust).
Cabaran anda:
Tulis satu fungsi yang menggabungkan beberapa input channel ke dalam satu output channel. Gunakan gelung select. Tambahkan timeout 500ms. Pastikan tiada goroutine yang bocor (leak).
Hantarkan penyelesaian anda di ruangan komen.