Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Tulis chan secara serentak.WaitGroup goroutine

Tulis chan secara serentak.WaitGroup goroutine

PHPz
PHPzke hadapan
2024-02-09 17:00:10647semak imbas

在sync.WaitGroup goroutine中写入chan

Editor PHP Youzi akan memperkenalkan kaedah menulis chan secara sync.WaitGroup goroutine. Dalam pengaturcaraan serentak, sync.WaitGroup ialah mekanisme penyegerakan yang sangat berguna yang boleh menunggu pelaksanaan sekumpulan goroutin selesai. Walau bagaimanapun, kadangkala kita perlu menulis keputusan kepada chan selepas goroutine menyelesaikan pelaksanaan untuk penggunaan oleh goroutine lain. Artikel ini akan memperkenalkan secara terperinci cara melaksanakan fungsi ini secara segerak. WaitGroup goroutine, mari lihat!

Kandungan soalan

Saya mendapat senarai item daripada titik akhir API. Kemudian, untuk setiap projek, saya membuat permintaan API lain untuk mendapatkan data tentang projek individu.

Saya tidak boleh membuat permintaan API kedua untuk setiap projek pada masa yang sama kerana token API saya adalah terhad dan jika saya membuat terlalu banyak permintaan pada masa yang sama, saya akan terbantut.

Walau bagaimanapun, data tindak balas API awal boleh dibahagikan kepada beberapa halaman, yang membolehkan saya memproses halaman data secara serentak.

Selepas beberapa penyelidikan, kod di bawah melakukan apa yang saya mahukan:

func main() {
    // pretend paginated results from initial API request
    page1 := []int{1, 2, 3}
    page2 := []int{4, 5, 6}
    page3 := []int{7, 8, 9}
    pages := [][]int{page1, page2, page3}

    results := make(chan string)

    var wg sync.WaitGroup
    for i := range pages {
        wg.Add(1)
        go func(i int) {
            defer wg.Done()
            for j := range pages[i] {
                // simulate making additional API request and building the report
                time.Sleep(500 * time.Millisecond)

                result := fmt.Sprintf("Finished creating report for %d", pages[i][j])
                results <- result
            }

        }(i)
    }

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

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

Saya ingin memahami mengapa ia berfungsi:

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

Percubaan pertama saya tidak berjaya - saya fikir saya boleh membaca hasilnya apabila wg.Wait() 之后遍历通道,并且我会在结果写入 results saluran.

func main() {
    // pretend paginated results from initial API request
    page1 := []int{1, 2, 3}
    page2 := []int{4, 5, 6}
    page3 := []int{7, 8, 9}
    pages := [][]int{page1, page2, page3}

    results := make(chan string)

    var wg sync.WaitGroup
    for i := range pages {
        wg.Add(1)
        go func(i int) {
            defer wg.Done()
            for j := range pages[i] {
                // simulate making additional API request and building the report
                time.Sleep(500 * time.Millisecond)

                result := fmt.Sprintf("Finished creating report for %d", pages[i][j])
                results <- result
            }

        }(i)
    }

    // does not work
    wg.Wait()
    close(results)

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

Penyelesaian

Pada percubaan pertama anda:

  1. Groutine utama menjadikan 3 goroutine meletakkan nilai ke dalam saluran hasil.
  2. Coroutine utama menunggu semua coroutine selesai.
  3. Salah satu goroutine meletakkan nilai ke dalam saluran hasil dan mengisi saluran (saiz saluran ialah 1 rentetan).
  4. Kini ketiga-tiga goroutin tidak lagi boleh meletakkan nilai ke dalam saluran hasil dan tidur sehingga saluran keputusan dikeluarkan.
  5. Semua gorouti dalam keadaan tidur. Anda sedang menemui jalan buntu.

Pada percubaan kedua:

  1. Groutine utama mengandungi 4 goroutine.
  2. 3 gorout untuk meletakkan nilai ke dalam saluran hasil.
  3. Groutine yang satu lagi (saya panggil yang ke-4) menunggu sehingga 3 goroutine ini habis.
  4. Pada masa yang sama, coroutine utama menunggu nilai dalam saluran hasil (untuk gelung)
  5. Dalam kes ini, jika salah satu goroutine meletakkan nilai dalam saluran hasil, ia menyekat baki tiga goroutin yang mengeluarkan nilai daripada saluran hasil, dengan itu menyahsekat goroutin yang lain.
  6. Jadi kesemua 3 goroutine meletakkan nilai masing-masing dan berakhir
  7. Kemudian goroutine keempat menutup saluran
  8. Gourutine utama menamatkannya untuk gelung.

Atas ialah kandungan terperinci Tulis chan secara serentak.WaitGroup goroutine. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam