Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Gabungan cekap Golang WaitGroup dan kumpulan coroutine

Gabungan cekap Golang WaitGroup dan kumpulan coroutine

王林
王林asal
2023-09-28 17:22:491211semak imbas

Golang WaitGroup和协程池的高效结合

Gabungan cekap Golang WaitGroup dan kumpulan coroutine memerlukan contoh kod khusus

Pengenalan:
Bahasa Go ialah bahasa yang menekankan pengaturcaraan serentak dan mencapai pelaksanaan serentak yang cekap melalui coroutine (goroutine). Dalam sesetengah senario di mana berbilang tugasan perlu dilaksanakan serentak, gabungan WaitGroup dan kumpulan coroutine boleh meningkatkan kecekapan pelaksanaan dan penggunaan sumber program dengan berkesan. Artikel ini akan memperkenalkan cara menggunakan WaitGroup dan kumpulan coroutine di Golang untuk mencapai pengaturcaraan serentak yang cekap dan menyediakan contoh kod khusus.

1. Pengenalan kepada WaitGroup
WaitGroup ialah alat dalam bahasa Go yang digunakan untuk menunggu selesainya pelaksanaan sekumpulan coroutine. Kod sumbernya ditakrifkan seperti berikut:

type WaitGroup struct {
    noCopy noCopy

    // 64位的值:高32位存储计数器,低32位存储等待计数器
    // 这个变量可以被原子操作加载和存储。
    // 在64位同步原语中,它必须在64位边界对齐。
    // 是一个强制的要求。
    state1 [3]uint32
}

WaitGroup biasanya dibuat dalam goroutine utama, dan kemudian setiap sub-goroutine dalam goroutine utama memanggil kaedah Tambah untuk meningkatkan pembilang, dan selepas pelaksanaan selesai, kaedah Selesai adalah digunakan untuk mengurangkan kaunter. Goroutine utama boleh menunggu kaunter kembali kepada sifar melalui kaedah Tunggu. Kod sampel khusus adalah seperti berikut:

package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup
    wg.Add(3)

    go func() {
        defer wg.Done()
        fmt.Println("Task 1 executing")
    }()

    go func() {
        defer wg.Done()
        fmt.Println("Task 2 executing")
    }()

    go func() {
        defer wg.Done()
        fmt.Println("Task 3 executing")
    }()

    wg.Wait()
    fmt.Println("All tasks completed")
}

Dalam contoh di atas, kami mencipta objek WaitGroup dan kemudian menambah pembilang dengan memanggil kaedah Tambah. Seterusnya, kami mencipta tiga sub-goroutin, dan selepas setiap goroutine dilaksanakan, kaunter dikurangkan melalui kaedah Selesai. Akhirnya, goroutine utama menunggu kaunter kembali ke sifar dengan memanggil kaedah Tunggu. Apabila semua tugas selesai, program akan mengeluarkan "Semua tugas selesai".

2. Pengenalan kepada kumpulan coroutine
Dalam pengaturcaraan serentak, kumpulan goroutine ialah mod yang biasa digunakan. Dengan mencipta bilangan goroutin yang tetap dan mengagihkan tugas secara sama rata kepada mereka, anda boleh mengelakkan overhed untuk mencipta dan memusnahkan gorouti secara berterusan. Dalam bahasa Go, anda boleh menggunakan saluran untuk melaksanakan kumpulan coroutine. Kod sampel khusus adalah seperti berikut:

package main

import (
    "fmt"
    "sync"
)

func worker(id int, jobs <-chan int, results chan<- int) {
    for j := range jobs {
        fmt.Println("Worker", id, "started job", j)
        fib := fibonacci(j)
        fmt.Println("Worker", id, "finished job", j)
        results <- fib
    }
}

func fibonacci(n int) int {
    if n <= 1 {
        return n
    }

    return fibonacci(n-1) + fibonacci(n-2)
}

const numJobs = 5
const numWorkers = 3

func main() {
    jobs := make(chan int, numJobs)
    results := make(chan int, numJobs)

    var wg sync.WaitGroup
    wg.Add(numWorkers)

    for w := 1; w <= numWorkers; w++ {
        go func(id int) {
            defer wg.Done()
            worker(id, jobs, results)
        }(w)
    }

    for j := 1; j <= numJobs; j++ {
        jobs <- j
    }
    close(jobs)

    wg.Wait()

    for r := 1; r <= numJobs; r++ {
        fmt.Println(<-results)
    }
}

Dalam contoh di atas, kami mentakrifkan fungsi pekerja, yang membaca tugas yang belum selesai daripada saluran kerja, kemudian melaksanakan tugas dan menghantar keputusan ke saluran hasil. Kami mencipta saluran pekerjaan dan saluran hasil untuk melaksanakan fungsi kumpulan coroutine dengan mengagihkan tugas dan mendapatkan hasil.

Dalam fungsi utama, kami menggunakan WaitGroup untuk menunggu semua pekerja (goroutine) menyelesaikan pelaksanaan tugas. Kemudian, kami menghantar tugasan untuk dilaksanakan ke saluran kerja dan menutup saluran selepas pelaksanaan. Akhirnya, kami mendapat hasil pengiraan daripada saluran keputusan dan mengeluarkannya.

3. Kes gabungan WaitGroup dan kumpulan coroutine yang cekap
Seterusnya, kami akan menggabungkan dua konsep di atas untuk memperkenalkan cara menggunakan WaitGroup dan kumpulan coroutine dengan berkesan untuk melaksanakan pengaturcaraan serentak. Kod sampel khusus adalah seperti berikut:

package main

import (
    "fmt"
    "sync"
)

func worker(id int, jobs <-chan int, results chan<- int) {
    for j := range jobs {
        fmt.Println("Worker", id, "started job", j)
        fib := fibonacci(j)
        fmt.Println("Worker", id, "finished job", j)
        results <- fib
    }
}

func fibonacci(n int) int {
    if n <= 1 {
        return n
    }

    return fibonacci(n-1) + fibonacci(n-2)
}

const numJobs = 5
const numWorkers = 3

func main() {
    var wg sync.WaitGroup
    wg.Add(numWorkers)

    jobs := make(chan int, numJobs)
    results := make(chan int, numJobs)

    for w := 1; w <= numWorkers; w++ {
        go func(id int) {
            defer wg.Done()
            worker(id, jobs, results)
        }(w)
    }

    for j := 1; j <= numJobs; j++ {
        jobs <- j
    }
    close(jobs)

    go func() {
        wg.Wait()
        close(results)
    }()

    for r := range results {
        fmt.Println(r)
    }
}

Dalam contoh di atas, kami mencipta objek WaitGroup dan menambah pembilang dengan memanggil kaedah Tambah. Kemudian, kami mencipta saluran pekerjaan dan saluran hasil untuk mengagihkan tugas dan mendapatkan hasil. Kami mencipta bilangan pekerja tetap (goroutine) dan menggunakan kaedah Tunggu untuk menunggu mereka menyelesaikan tugas mereka.

Dalam fungsi utama, kami menghantar tugasan untuk dilaksanakan ke saluran kerja dan menutup saluran selepas pelaksanaan. Kami kemudiannya memulakan coroutine untuk menunggu semua pekerja menyelesaikan tugas mereka dan menutup saluran keputusan apabila selesai. Akhir sekali, kami mengeluarkan hasil pengiraan dengan mendapatkannya daripada saluran hasil.

Kesimpulan:
Dengan menggabungkan WaitGroup dan kumpulan coroutine, kami boleh mencapai pengaturcaraan serentak dengan cekap. Dengan menggunakan WaitGroup untuk menunggu pelaksanaan kumpulan goroutine selesai, anda boleh memastikan bahawa goroutine utama terus dilaksanakan selepas semua tugasan selesai. Dengan menggunakan kumpulan coroutine, kita boleh mengelakkan overhed untuk kerap mencipta dan memusnahkan gorouti dan meningkatkan kecekapan pelaksanaan dan penggunaan sumber program.

Pengiraan jujukan Fibonacci dalam contoh kod hanyalah contoh tunjuk cara, dan boleh digantikan dengan tugas lain mengikut keperluan khusus dalam aplikasi sebenar. Menggunakan WaitGroup dan kumpulan coroutine, kami boleh mengawal bilangan tugasan yang dilaksanakan serentak dengan lebih baik dan menggunakan sumber pengkomputeran dengan lebih berkesan.

Walaupun bahasa Go menyediakan alatan dan ciri pengaturcaraan serentak yang kaya, anda masih perlu berhati-hati apabila menggunakannya. Penggunaan WaitGroup dan kumpulan coroutine yang betul boleh membantu kami mengurus dan menjadualkan gorout dengan lebih baik serta mencapai pengaturcaraan serentak yang cekap.

Atas ialah kandungan terperinci Gabungan cekap Golang WaitGroup dan kumpulan coroutine. 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