Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mari kita bincangkan tentang cara membuka berbilang coroutine dalam bahasa Go

Mari kita bincangkan tentang cara membuka berbilang coroutine dalam bahasa Go

PHPz
PHPzasal
2023-04-11 10:42:16850semak imbas

Dalam beberapa tahun kebelakangan ini, bahasa Go telah menjadi salah satu bahasa pengaturcaraan paling popular​​ dalam bidang Internet, dan mempunyai prestasi cemerlang dalam bidang konkurensi berskala besar dan prestasi tinggi. Apabila memproses permintaan serentak, membuka berbilang coroutine Go ialah cara penting untuk meningkatkan prestasi sistem dan kelajuan tindak balas. Jadi, bagaimana untuk membuka lebih banyak coroutine Go?

Goroutine dalam bahasa Go adalah serupa dengan benang, tetapi lebih ringan dan cekap. Menggunakan goroutine, kami boleh melaksanakan pemprosesan berbilang tugas dengan mudah seperti pengkomputeran selari dan IO tak segerak.

Mula-mula, mari kita lihat contoh mudah yang menunjukkan cara menggunakan goroutine untuk mengendalikan berbilang permintaan pada masa yang sama:

func main() {
    urls := []string{
        "http://www.google.com/",
        "http://www.apple.com/",
        "http://www.microsoft.com/",
        "http://www.facebook.com/",
    }

    for _, url := range urls {
        go request(url)
    }

    time.Sleep(time.Second)
}

func request(url string) {
    resp, err := http.Get(url)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(url, len(body))
}

Kod di atas menunjukkan cara mengambil berbilang permintaan secara serentak Untuk kandungan laman web, kami menggunakan goroutine untuk mengendalikan setiap permintaan secara serentak. Walau bagaimanapun, dalam aplikasi sebenar, jika kami menggunakan kod di atas secara langsung, ia boleh menyebabkan terlalu banyak goroutine dibuat, malah boleh menyebabkan sistem ranap.

Oleh itu, kita perlu mengawal bilangan goroutine melalui pengoptimuman supaya ia boleh berjalan dalam toleransi beban sistem.

Pertama sekali, kita boleh mengawal konkurensi dengan mengehadkan bilangan goroutin. Dalam bahasa Pergi, anda boleh menggunakan kumpulan tunggu (jenis alat dalam pakej penyegerakan) untuk mengawal bilangan goroutine.

Berikut ialah contoh program:

func main() {
    urls := []string{
        "http://www.google.com/",
        "http://www.apple.com/",
        "http://www.microsoft.com/",
        "http://www.facebook.com/",
    }

    var wg sync.WaitGroup
    for _, url := range urls {
        wg.Add(1)
        go func(url string) {
            request(url)
            wg.Done()
        }(url)
    }

    wg.Wait()
}

func request(url string) {
    resp, err := http.Get(url)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(url, len(body))
}

Dalam kod di atas, WaitGroup digunakan untuk mengawal bilangan goroutine. Apabila goroutine memanggil kaedah waitgroup.Add(1), ini bermakna goroutine perlu dimulakan untuk memproses permintaan dan apabila goroutine selesai memproses permintaan, ia perlu memanggil kaedah waitgroup.Done() yang bermaksud; bahawa satu tugas telah diselesaikan.

Selain itu, kita juga boleh menggunakan mekanisme penimbalan pernyataan go untuk mengawal konkurensi. Saluran dalam bahasa Go boleh membantu kami merealisasikan komunikasi antara gorouti dan boleh digunakan untuk mengawal penjadualan antara gorouti. Saluran cache boleh mengehadkan konkurensi dan dengan itu mengawal bilangan goroutine.

Berikut ialah contoh program:

func main() {
    urls := []string{
        "http://www.google.com/",
        "http://www.apple.com/",
        "http://www.microsoft.com/",
        "http://www.facebook.com/",
    }

    var wg sync.WaitGroup
    ch := make(chan string, 2)
    for _, url := range urls {
        ch <- url
        wg.Add(1)
        go func() {
            defer wg.Done()
            request(<-ch)
        }()
    }

    wg.Wait()
}

func request(url string) {
    resp, err := http.Get(url)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(url, len(body))
}

Dalam kod di atas, kami menggunakan saluran cache dan mencipta saluran dengan kapasiti 2 untuk mengehadkan bilangan goroutine . Pada masa yang sama, kami menggunakan WaitGroup untuk menunggu semua goroutine selesai sebelum program keluar.

Ringkasnya, untuk membuka berbilang coroutine Go, anda perlu melakukan perkara berikut:

  1. Kawal bilangan goroutine secara munasabah untuk mengelakkan beban sistem yang berlebihan disebabkan oleh penciptaan goroutine yang berlebihan.
  2. Gunakan mekanisme seperti WaitGroup dan saluran untuk mengawal konkurensi dan mengelakkan masalah persaingan dan penjadualan antara gorouti.
  3. Gunakan sumber sistem yang munasabah, proses permintaan secara serentak dan tingkatkan kelajuan tindak balas dan prestasi sistem.

Sudah tentu, perkara di atas hanyalah idea dan kaedah untuk membuka lebih banyak coroutine Go Dalam pengeluaran sebenar, kita masih perlu mengoptimumkan dan mereka bentuk mengikut keperluan tertentu. Saya percaya bahawa dengan pengetahuan asas ini, anda akan dapat menangani masalah berbilang coroutine dalam bahasa Go dengan lebih baik.

Atas ialah kandungan terperinci Mari kita bincangkan tentang cara membuka berbilang coroutine dalam bahasa Go. 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