Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Corak Pengeluar-Pengguna

Corak Pengeluar-Pengguna

王林
王林asal
2024-07-27 14:35:15745semak imbas

Producer-Consumer Pattern

Dalam siaran ini, Goroutine dan saluran diperkenalkan. Ini adalah 2 daripada binaan yang paling berguna semasa pergi. Bersama-sama, apabila digunakan dengan betul, mereka memberikan pembangun fleksibiliti yang hebat dalam menangani konkurensi. Mereka adalah salah satu topik yang paling biasa dalam temu bual.

Laksanakan corak pengguna pengeluar yang mudah dalam perjalanan.

var buffer = make(chan int, 5)

func produce(wg *sync.WaitGroup) {
    defer wg.Done()
    for i := 0; i < 10; i++ {
        buffer <- i
        time.Sleep(time.Millisecond * time.Duration(rand.Intn(100)))
    }
    fmt.Println("producer done")
}

func consume(wg *sync.WaitGroup) {
    defer wg.Done()
    for data := range buffer {
        fmt.Println(data)
        time.Sleep(time.Millisecond * time.Duration(rand.Intn(400)))
    }
    fmt.Println("consumer done")
}

func main() {
    var producerWg sync.WaitGroup
    var consumerWg sync.WaitGroup
    producerWg.Add(1)
    go produce(&producerWg)
    go func() {
        producerWg.Wait()
        close(buffer)
        fmt.Println("closed channel")
    }()
    consumerWg.Add(1)
    go consume(&consumerWg)
    consumerWg.Wait()
    fmt.Println("done")
}

Ini adalah salah satu pelaksanaan yang paling mudah; tetapi coraknya agak biasa. Kami mempunyai nilai 'menghasilkan' benang dan benang yang mesti 'menggunakan' nilai tersebut. Dalam golang, cara untuk menghantar nilai ini antara utas ialah saluran.

Kami bermula dengan mencipta saluran untuk integer. Kemudian buat rutin yang melaksanakan fungsi pengeluar dan pengguna.

Dalam sebarang situasi berbilang benang, penyegerakan adalah masalah. Golang mencipta WaitGroup sebagai salah satu cara untuk melaksanakan penyegerakan. Ia berfungsi hanya sebagai pembilang dan utas yang perlu disegerakkan akan menunggu sehingga kiraan ialah 0. Urutan kawalan menggunakan fungsi Done() untuk mengurangkan pembilang.

Dalam masalah ini, kami mencipta WaitGroup untuk kedua-dua pengeluar dan pengguna, memulakan kedua-duanya untuk mengira 1 (menggunakan fungsi Add()).

Urut utama melancarkan pengeluar, pengguna dan utas sebaris yang menunggu pengeluar kemudian menunggu pengguna selesai.

Urutan pengeluar mula menghantar data seperti biasa. Apabila selesai, ia menggunakan WaitGroup untuk menandakan bahawa ia telah selesai menghantar ke saluran. Gorutin sebaris menunggu pada WaitGroup pengeluar yang menutup saluran. Jika saluran tidak pernah ditutup, pengguna akan tidur selamanya menunggu lebih banyak data dan proses itu tidak akan ditamatkan.

Apabila pengguna tidak mempunyai data lagi (kerana saluran telah ditutup), ia memberitahu WaitGroup kedua bahawa ia telah selesai.

Urut utama yang melancarkan rangkaian pengeluar dan pengguna menunggu sehingga WaitGroup pengguna membenarkannya selesai. Ini menghalang utas utama daripada ditamatkan lebih awal yang akan membunuh semua utas dalam proses.

Ini bukan satu-satunya cara untuk melaksanakan corak pengeluar-pengguna.

Terdapat juga beberapa isu seperti penamatan luaran daripada isyarat seperti SIGTERM dan SIGINT yang perlu ditangani untuk kod pengeluaran. Ini ialah demonstrasi mudah yang menunjukkan asasnya.

Bagaimana lagi anda akan melaksanakannya? Apakah yang tiada dalam pelaksanaan di atas? Siarkan ulasan atau pautan anda ke pelaksanaan lain di bawah.

Terima kasih!

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

Atas ialah kandungan terperinci Corak Pengeluar-Pengguna. 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