Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Kerjasama yang elegan antara Go WaitGroup dan baris gilir mesej

Kerjasama yang elegan antara Go WaitGroup dan baris gilir mesej

WBOY
WBOYasal
2023-09-27 13:17:02555semak imbas

Go WaitGroup与消息队列的优雅协作

Kerjasama elegan Go WaitGroup dengan baris gilir mesej memerlukan contoh kod khusus

Dalam pembangunan perisian moden, pengaturcaraan serentak merupakan topik yang tidak dapat dielakkan. Terutamanya apabila berurusan dengan data berskala besar dan permintaan serentak yang tinggi, adalah sangat penting untuk mengurus operasi serentak dengan berkesan.

Sebagai bahasa pengaturcaraan serentak yang berkuasa, bahasa Go menyediakan primitif serentak yang kaya untuk membantu pembangun mencapai operasi serentak yang cekap. Antaranya, WaitGroup dan baris gilir mesej digunakan secara meluas untuk melaksanakan mod kerjasama tak segerak.

WaitGroup ialah struktur penting dalam pustaka standard bahasa Go. Ia boleh membantu kami menunggu pelaksanaan kumpulan goroutin selesai. WaitGroup sangat berguna apabila kita memulakan berbilang goroutine dan mahu mereka selesai melaksanakan sebelum meneruskan ke langkah seterusnya.

Proses menunggu sekumpulan goroutine untuk menyelesaikan pelaksanaan boleh dicapai melalui tiga kaedah dalam WaitGroup:

  • Add(n int): Add n waiting goroutine ke WaitGroup.
  • Done(): Kaedah Done() dipanggil selepas setiap goroutine dilaksanakan, menunjukkan bahawa goroutine telah dilaksanakan.
  • Tunggu(): goroutine utama memanggil kaedah Tunggu() untuk menunggu semua goroutine menunggu selesai pelaksanaan.

Berikut ialah contoh kod mudah yang menggunakan WaitGroup untuk melaksanakan fungsi menunggu beberapa goroutin untuk menyelesaikan pelaksanaan:

package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    var wg sync.WaitGroup
    
    for i := 0; i < 5; i++ {
        wg.Add(1) // 启动5个goroutine,需要调用5次Add(1)
        go func(i int) {
            defer wg.Done() // 每个goroutine执行完毕后调用Done()
            fmt.Println("goroutine", i, "started")
            time.Sleep(time.Second)
            fmt.Println("goroutine", i, "finished")
        }(i)
    }

    wg.Wait() // 主goroutine等待所有goroutine执行完毕
    fmt.Println("all goroutines finished")
}

Dalam kod di atas, kami memberitahu WaitGroup melalui kaedah Tambah WaitGroup bahawa kami mempunyai 5 goroutin untuk menunggu untuk, dan kemudian kaedah Selesai dipanggil selepas setiap goroutine dilaksanakan, dan akhirnya goroutine utama memanggil kaedah Tunggu untuk menunggu semua goroutine dilaksanakan.

Baris gilir mesej ialah satu lagi corak pengaturcaraan serentak yang biasa digunakan, yang sangat mudah apabila mengendalikan tugas tak segerak dan menyahgandingkan komunikasi antara komponen yang berbeza. Baris gilir mesej boleh mengendalikan penjadualan dan pengagihan tugas serentak dengan baik, supaya setiap tugas boleh dilaksanakan mengikut permintaan.

Dalam bahasa Go, kita boleh menggunakan saluran untuk melaksanakan fungsi baris gilir mesej. Berikut ialah contoh kod mudah yang menggunakan saluran untuk melaksanakan fungsi baris gilir mesej:

package main

import "fmt"

func main() {
    tasks := make(chan int) // 创建一个整数类型的channel

    go func() {
        for i := 1; i <= 10; i++ {
            tasks <- i // 把任务发送到channel中
        }
        close(tasks) // 关闭channel,表示没有更多任务了
    }()

    for task := range tasks {
        fmt.Println("processing task", task)
        // 处理任务的逻辑...
    }

    fmt.Println("all tasks finished")
}

Dalam kod di atas, kami mencipta saluran jenis integer, dan kemudian menghantar 10 tugasan ke saluran dalam goroutine yang berasingan. Goroutin utama menerima tugasan daripada saluran melalui gelung dan mengendalikan logik tugasan.

Menggabungkan WaitGroup dan baris gilir mesej boleh mencapai corak pengaturcaraan serentak yang lebih kompleks. Contohnya, dalam sistem penjadualan tugas, kita boleh menggunakan WaitGroup untuk menunggu semua tugasan dilaksanakan dan setiap tugas boleh menggunakan baris gilir mesej secara bebas untuk memproses subtugas tertentu.

Berikut ialah contoh kod yang menunjukkan cara menggunakan WaitGroup dan baris gilir mesej untuk bekerjasama bagi penjadualan tugas:

package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    var wg sync.WaitGroup
    tasks := make(chan int) // 创建一个整数类型的channel

    wg.Add(1) // 增加1个等待的goroutine
    go func() {
        defer wg.Done() // 当前goroutine执行完毕后调用Done()

        for task := range tasks {
            fmt.Println("processing task", task)
            // 处理任务的逻辑...
            time.Sleep(time.Second)
        }
    }()

    for i := 1; i <= 10; i++ {
        tasks <- i // 把任务发送到channel中
    }
    close(tasks) // 关闭channel,表示没有更多任务了

    wg.Wait() // 等待所有任务执行完毕

    fmt.Println("all tasks finished")
}

Dalam kod di atas, kami mencipta saluran jenis integer untuk menerima tugas. Kemudian goroutine dimulakan, di mana tugas diterima dari saluran dan diproses. Goroutine utama bertanggungjawab untuk menghantar tugasan ke saluran dan menunggu selepas semua tugasan telah dilaksanakan.

Melalui kerjasama elegan WaitGroup dan baris gilir mesej, kami boleh mencapai pengaturcaraan serentak yang cekap. WaitGroup boleh membantu kami mengawal susunan pelaksanaan operasi serentak dan menunggu semua tugasan selesai. Barisan mesej boleh merealisasikan penjadualan dinamik dan pengagihan tugas dan pemprosesan tugasan tak segerak. Gabungan kedua-duanya memberikan kami idea dan alatan pengaturcaraan yang lebih serentak, membolehkan kami melaksanakan operasi serentak yang kompleks dengan lebih baik.

Ringkasnya, kerjasama elegan antara Go WaitGroup dan baris gilir mesej memainkan peranan penting dalam pengaturcaraan serentak. Penggunaan yang betul boleh membantu kami mencapai operasi serentak yang cekap dan boleh dipercayai. Sama ada anda berurusan dengan data berskala besar atau permintaan serentak yang tinggi, ia adalah model pengaturcaraan serentak yang sangat berguna.

Atas ialah kandungan terperinci Kerjasama yang elegan antara Go WaitGroup dan baris gilir mesej. 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