Corak Fanout

PHPz
PHPzasal
2024-07-28 11:10:22597semak imbas

Fanout Pattern

Mari kita lihat sekilas corak fanout dalam Go. Secara amnya, fanout digunakan untuk melaksanakan beberapa tugasan secara serentak.

Sebagai contoh, katakan anda mempunyai saluran paip data dan anda ingin memproses item individu. Kami boleh menggunakan rutin dan saluran go untuk membahagikan item semasa kami menerimanya, kemudian memproses item individu (masukkan dalam dB sebagai contoh).

Ia adalah corak mudah untuk dilaksanakan; tetapi anda perlu menguruskan saluran untuk mengelakkan kebuntuan.

// produce is simulating our single input as a channel
func produce(id int) chan int {
    ch := make(chan int)
    go func() {
        for i := 0; i < 10; i++ {
            ch <- rand.Intn(20)
        }
        fmt.Printf("producer %d done\n", id)
        close(ch) // this is important!!!
    }()
    return ch
}

func worker(id int, jobs chan int, wg *sync.WaitGroup) {
    for value := range jobs {
        odd := "even"
        if (value & 1) == 1 {
            odd = "odd"
        }
        fmt.Printf("worker: %d, got %d is %s\n", id, value, odd)
    }
    wg.Done()
}

func main() {
    inputCh := produce(1)

    numWorkers := 3
    jobs := make(chan int)

    // split input into individual jobs
    go func() {
        for value := range inputCh {
            jobs <- value
        }
        close(jobs) // this is important!!!
    }()

    // fan-out
    var wg sync.WaitGroup
    for i := 0; i < numWorkers; i++ {
        wg.Add(1)
        go worker(i, jobs, &wg)
    }
    wg.Wait()

    fmt.Println("done")
}

Idea utama di sini ialah terdapat urutan data yang perlu dikendalikan oleh bilangan pekerja tetap.

Untuk input, kami mencipta urutan nombor rawak dan meletakkannya dalam saluran. Kami memindahkan mereka ke saluran lain di mana pekerja akan menarik 'pekerjaan' mereka.

Dalam contoh ini, tidak semestinya perlu mengalihkan input ke saluran kerja. Kita boleh dengan mudah meminta pekerja keluar dari saluran input; ia hanya dilakukan untuk kejelasan di sini.

Kami kemudian menghantar pelancaran bilangan pekerja tetap sebagai goroutin. Setiap pekerja akan menarik diri daripada saluran kerja sehingga tiada lagi data untuk diproses pada masa itu ia menandakan WaitGroup bahawa ia telah selesai.

Urut utama menggunakan WaitGroup untuk memastikan ia tidak selesai sehingga semua pekerja selesai, iaitu semua kerja telah diproses.

Perkara penting untuk menyebut bahawa corak ini tidak meletakkan sebarang jaminan pada susunan pemprosesan urutan input. Ini mungkin baik dalam banyak keadaan. Sebagai contoh, jujukan input ialah rekod data yang mengandungi cap masa mereka sendiri dan matlamatnya adalah untuk menyimpan rekod dalam dB. Fan-out dalam kes ini boleh diterima.

Nota terakhir, anda akan melihat beberapa ulasan mengenai penutupan saluran setelah semua data dalam urutan telah dihantar. Ini kritikal. Pengendali julat yang menarik dari saluran akan tidur apabila tiada lagi data. Anda boleh mengesahkan ini dengan mengulas sekali daripada kenyataan close() yang akan menyebabkan keadaan kebuntuan. Goroutine dan saluran sangat berkuasa tetapi anda perlu menggunakannya dengan bijak.

Apa yang anda akan lakukan berbeza? Bagaimanakah kita boleh menambah baik contoh ini? Tinggalkan komen anda di bawah.

Terima kasih!

Kod untuk siaran ini dan semua siaran dalam siri ini boleh didapati di sini

Atas ialah kandungan terperinci Corak Fanout. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn