Menggunakan Tamat Masa dengan Saluran Go
Dalam Go, goroutine dan saluran menyediakan model serentak yang berkuasa. Walau bagaimanapun, apabila menggunakan mekanisme ini, adalah penting untuk mengendalikan tamat masa dengan betul untuk mengelakkan kemungkinan isu.
Satu soalan biasa timbul apabila menggunakan tamat masa dengan saluran: mengapakah kes tamat masa tidak dapat dilaksanakan? Mari kita terokai perkara ini dan sediakan penyelesaian untuk memastikan pengendalian tamat masa yang betul.
Kod Asal:
import "fmt" import "time" 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 } func main() { fmt.Println(IsReachable([]string{"url1"})) }
Isu:
Dengan kod ini, semua URL sentiasa dilaporkan sebagai boleh dicapai, tanpa mengira sambungan sebenar. Kes tamat masa tidak dapat dilaksanakan kerana fungsi semak menyekat goroutine semasa.
Penyelesaian 1: Jalankan Fungsi Semak dalam Goroutine Berasingan:
Untuk menyelesaikan masalah ini , alihkan fungsi semak ke dalam goroutine yang berasingan dan gunakan saluran lain untuk menyampaikan hasil:
package main import "fmt" import "time" 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 } func main() { fmt.Println(IsReachable([]string{"url1"})) }
Penyelesaian 2: Mulakan Tamat Masa Tunggal untuk Semua URL:
Sebagai alternatif, jika matlamatnya adalah untuk melaporkan kebolehcapaian berdasarkan mana-mana semakan yang berjaya, pertimbangkan untuk memudahkan pengendalian tamat masa dengan menggunakan tamat masa tunggal untuk semua URL:
package main import "fmt" import "time" func check(u string, ch chan<- bool) { time.Sleep(4 * time.Second) ch <- true } func IsReachable(urls []string) bool { ch := make(chan bool, len(urls)) for _, url := range urls { go check(url, ch) } time.AfterFunc(time.Second, func() { ch <- false }) return <-ch } func main() { fmt.Println(IsReachable([]string{"url1", "url2"})) }
Dengan menangani tamat masa pengendalian dengan betul, pembangun boleh memastikan bahawa kod Go mereka menggambarkan kebolehcapaian URL dengan tepat, memberikan pengalaman aplikasi yang lebih dipercayai dan konsisten.
Atas ialah kandungan terperinci Mengapa Kes Tamat Masa Tidak Dilaksanakan Apabila Menggunakan Saluran Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!