Rumah >pembangunan bahagian belakang >Golang >Bagaimana untuk Melaksanakan Tamat Masa dengan Betul dalam Go Goroutines dengan Saluran?

Bagaimana untuk Melaksanakan Tamat Masa dengan Betul dalam Go Goroutines dengan Saluran?

DDD
DDDasal
2024-11-08 14:57:02301semak imbas

How to Implement Timeouts Correctly in Go Goroutines with Channels?

Menggunakan Tamat Masa dengan Saluran dalam Go

Gorutin dan saluran menyediakan mekanisme yang berkuasa untuk pengaturcaraan serentak dalam Go. Walau bagaimanapun, pengendalian tamat masa dalam gorouti boleh menjadi rumit.

Dalam senario di mana anda ingin menyemak kebolehcapaian senarai URL menggunakan gorout dan tamat masa, mungkin terdapat situasi di mana tamat masa tidak dapat dilaksanakan walaupun jika sesetengah URL tidak dapat dicapai.

Mari kita analisa kod yang disediakan:

func check(u string) bool {
    time.Sleep(4 * time.Second)
    return true
}

func IsReachable(urls []string) bool {
    ch := make(chan bool, 1)
    for _, url := range urls {
        go func(u string) {
            select {
            case ch <- check(u):
            case <-time.After(time.Second):
                ch <- false
            }
        }(url)
    }
    return <-ch
}

Isunya terletak dalam fungsi semak. Apabila anda menggunakan masa.Tidur dalam goroutine, ia menjeda goroutine semasa, yang dalam kes ini ialah goroutine yang menjalankan fungsi semakan. Semasa fungsi semak dijeda, penyataan pilih dalam goroutine luar masih akan cuba dijalankan.

Dalam kes ini, kedua-dua cabang penyataan pilih (menyemak keputusan atau tamat masa) akan dapat dijalankan selepas 4 saat apabila cek kembali. Walau bagaimanapun, memandangkan kedua-dua cawangan boleh dijalankan, masa jalan boleh memilih untuk melaksanakan salah satu, yang boleh menyebabkan sentiasa kembali benar.

Untuk menyelesaikannya, anda perlu mencipta goroutine baharu untuk setiap fungsi semakan, seperti yang ditunjukkan dalam kod yang diperbetulkan di bawah:

func check(u string, checked chan<- bool) {
    time.Sleep(4 * time.Second)
    checked <- true
}

func IsReachable(urls []string) bool {
    ch := make(chan bool, 1)
    for _, url := range urls {
        go func(u string) {
            checked := make(chan bool)
            go check(u, checked)
            select {
            case ret := <-checked:
                ch <- ret
            case <-time.After(time.Second):
                ch <- false
            }
        }(url)
    }
    return <-ch
}

Dalam kes ini, fungsi semakan dilaksanakan dalam goroutine yang berasingan, memastikan ia tidak menjeda goroutine luar dan tamat masa boleh dilaksanakan dengan betul.

Atas ialah kandungan terperinci Bagaimana untuk Melaksanakan Tamat Masa dengan Betul dalam Go Goroutines dengan Saluran?. 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