1. Jalankan Setiap Contoh: Jangan baca kod sahaja. Taipkannya, jalankan dan perhatikan tingkah lakunya.⚠️ Bagaimana untuk meneruskan siri ini?
2. Eksperimen dan Pecah Perkara: Alih keluar tidur dan lihat apa yang berlaku, tukar saiz penimbal saluran, ubah suai kiraan goroutine.
Memecahkan perkara mengajar anda cara ia berfungsi
3. Sebab Tentang Gelagat: Sebelum menjalankan kod yang diubah suai, cuba ramalkan hasilnya. Apabila anda melihat tingkah laku yang tidak dijangka, berhenti seketika dan fikirkan mengapa. Cabar penjelasan.
4. Bina Model Mental: Setiap visualisasi mewakili konsep. Cuba lukis gambar rajah anda sendiri untuk kod yang diubah suai.
Dalam catatan kami sebelum ini, kami meneroka corak konkurensi Generator, blok binaan corak konkurensi Go yang lain. Anda boleh membacanya di sini:
Sekarang, mari kita lihat bagaimana primitif ini bergabung untuk membentuk corak berkuasa yang menyelesaikan masalah dunia sebenar.
Dalam siaran ini kami akan membincangkan Corak Saluran Paip dan akan cuba menggambarkannya. Oleh itu, mari bersiap sedia kerana kita akan mengendalikan proses tersebut.
Saluran paip adalah seperti talian pemasangan di kilang, di mana setiap peringkat melaksanakan tugas tertentu pada data dan menghantar hasilnya ke peringkat seterusnya.
Kami membina saluran paip dengan menyambungkan goroutine dengan saluran, dengan setiap goroutine mewakili peringkat yang menerima data, memprosesnya dan menghantarnya ke peringkat seterusnya.
Mari kita laksanakan saluran paip mudah yang:
// Stage 1: Generate numbers func generate(nums ...int) <-chan int { out := make(chan int) go func() { defer close(out) for _, n := range nums { out <- n } }() return out } // Stage 2: Square numbers func square(in <-chan int) <-chan int { out := make(chan int) go func() { defer close(out) for n := range in { out <- n * n } }() return out } // Stage 3: Print numbers func print(in <-chan int) { for n := range in { fmt.Printf("%d ", n) } fmt.Println() } func main() { // Connect the pipeline numbers := generate(2, 3, 4) // Stage 1 squares := square(numbers) // Stage 2 print(squares) // Stage 3 }
✏️ Bait pantas
<-chan int menandakan saluran terima sahaja.
Saluran jenis <-chan int hanya boleh digunakan untuk menerima nilai, bukan untuk menghantarnya. Ini berguna untuk menguatkuasakan corak komunikasi yang lebih ketat dan mengelakkan penulisan secara tidak sengaja ke saluran oleh penerima.chan int Ini menandakan saluran dua arah.
Saluran jenis chan int boleh digunakan untuk menghantar dan menerima nilai.
Mari kita teruskan dan bayangkan contoh di atas:
Di sini anda boleh melihat setiap blok binaan saluran paip adalah goroutine mengikut corak penjana. Menyiratkan bahawa sebaik sahaja data sedia di mana-mana langkah langkah seterusnya dalam saluran paip boleh mula memprosesnya tidak seperti pemprosesan berjujukan.
Prinsip teras hendaklah:
mari kemas kini kod kami dengan beberapa pengendalian ralat yang betul.
type Result struct { Value int Err error } func generateWithError(nums ...int) <-chan Result { out := make(chan Result) go func() { defer close(out) for _, n := range nums { if n < 0 { out <- Result{Err: fmt.Errorf("negative number: %d", n)} return } out <- Result{Value: n} } }() return out } func squareWithError(in <-chan Result) <-chan Result { out := make(chan Result) go func() { defer close(out) for r := range in { if r.Err != nil { out <- r // Forward the error continue } out <- Result{Value: r.Value * r.Value} } }() return out } func main() { // Using pipeline with error handling for result := range squareWithError(generateWithError(2, -3, 4)) { if result.Err != nil { fmt.Printf("Error: %v\n", result.Err) continue } fmt.Printf("Result: %d\n", result.Value) } }
Mari kita ambil contoh untuk memahami dengan lebih baik, kami mempunyai aliran kerja pemprosesan data yang mengikut corak saluran paip seperti yang ditunjukkan di bawah.
? Setiap peringkat boleh dibangunkan, diuji dan diubah suai secara bebas
? Perubahan pada dalaman satu peringkat tidak menjejaskan peringkat lain
? Mudah untuk menambah peringkat baharu atau mengubah suai yang sedia ada
? Pemisahan kebimbangan yang jelas
Dan bahagian yang terbaik? Kami boleh menjalankan berbilang contoh setiap peringkat (pekerja) untuk keperluan yang lebih serentak seperti:
?? Hei tetapi bukankah itu Corak Konkurensi Kipas-Masuk dan Kipas-Keluar?
Bingo! Tangkapan yang baik di sana. Ia sememangnya corak Fan-Out, Fan-In, yang merupakan jenis corak saluran paip tertentu. Kami akan membincangkannya secara terperinci dalam siaran seterusnya jadi jangan risau ;)
memproses imej dalam saluran paip
// Stage 1: Generate numbers func generate(nums ...int) <-chan int { out := make(chan int) go func() { defer close(out) for _, n := range nums { out <- n } }() return out } // Stage 2: Square numbers func square(in <-chan int) <-chan int { out := make(chan int) go func() { defer close(out) for n := range in { out <- n * n } }() return out } // Stage 3: Print numbers func print(in <-chan int) { for n := range in { fmt.Printf("%d ", n) } fmt.Println() } func main() { // Connect the pipeline numbers := generate(2, 3, 4) // Stage 1 squares := square(numbers) // Stage 2 print(squares) // Stage 3 }
atau sesuatu yang rumit seperti saluran paip pemprosesan log
Corak ini sesuai untuk operasi terikat CPU di mana kerja boleh diproses secara bebas. Saluran paip mengagihkan kerja merentasi berbilang pekerja dan kemudian menggabungkan semula hasilnya. Ini amat berkesan apabila:
Corak ini membantu mengurus ketidakpadanan kelajuan antara peringkat saluran paip. Penampan bertindak sebagai penyerap hentak, membolehkan peringkat pantas berfungsi di hadapan tanpa disekat oleh peringkat yang lebih perlahan. Ini berguna apabila:
Corak ini mengoptimumkan operasi terikat I/O dengan mengumpulkan berbilang item ke dalam satu kelompok. Daripada memproses item satu demi satu, ia mengumpulkannya ke dalam kumpulan dan memprosesnya bersama-sama. Ini berkesan apabila:
Setiap corak ini boleh digabungkan mengikut keperluan. Sebagai contoh, anda mungkin menggunakan pemprosesan berkelompok dengan penskalaan mendatar, di mana berbilang pekerja setiap satu memproses kelompok item. Kuncinya ialah memahami kesesakan anda dan memilih corak yang sesuai untuk menanganinya.
Itu melengkapkan penyelaman mendalam kami ke dalam corak Penjana! Akan datang seterusnya, kami akan meneroka Corak konkurensi saluran paip, di mana kita akan melihat cara merantai penjana kami bersama-sama untuk membina aliran pemprosesan data yang berkuasa.
Jika anda mendapati siaran ini membantu, mempunyai sebarang pertanyaan atau ingin berkongsi pengalaman anda sendiri dengan penjana - saya ingin mendengar daripada anda dalam ulasan di bawah. Cerapan dan soalan anda membantu menjadikan penjelasan ini lebih baik untuk semua orang.
Jika anda terlepas panduan visual untuk goroutine dan saluran Golang, lihat di sini:
Nantikan lebih banyak corak konkurensi Go! ?
Atas ialah kandungan terperinci Corak Keselarasan Saluran Paip dalam Go: Panduan Visual Komprehensif. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!