Dengan kemajuan berterusan teknologi komputer, kecekapan pengendalian dan prestasi program moden telah menjadi isu yang semakin penting. Pengaturcaraan serentak ialah cara penting untuk meningkatkan kecekapan dan prestasi menjalankan program. Sebagai bahasa pengaturcaraan yang baru muncul, mekanisme goroutine dan saluran unik golang menjadikan pengaturcaraan serentak lebih mudah dan lebih cekap.
Artikel ini akan memperkenalkan konsep asas pengaturcaraan serentak golang, dan menggunakan beberapa contoh untuk menunjukkan cara menggunakan goroutin dan saluran untuk membina program serentak yang cekap.
1. Apakah itu goroutine
Goroutine ialah benang ringan dalam golang Saiz setiap goroutine hanya kira-kira 2KB, menggunakan memori dan sumber yang sangat sedikit. Selain itu, penjadual golang secara automatik akan memperuntukkan goroutine kepada utas fizikal yang berbeza untuk pelaksanaan, dengan itu mencapai pelaksanaan serentak.
Anda boleh memulakan goroutine melalui kata kunci go, contohnya:
package main import ( "fmt" "time" ) func printNums() { for i := 0; i < 5; i++ { fmt.Println(i) time.Sleep(time.Millisecond * 500) } } func main() { // 启动一个goroutine go printNums() // 继续执行主goroutine for i := 0; i < 5; i++ { fmt.Println("Hello") time.Sleep(time.Millisecond * 500) } }
Jalankan atur cara di atas, anda dapat melihat bahawa kedua-dua goroutine secara bergantian mengeluarkan nombor dan Hello, dengan itu mencapai pelaksanaan serentak.
2. Apakah itu saluran
Saluran di Golang ialah struktur data yang digunakan untuk komunikasi dan penyegerakan antara goroutine. Saluran boleh memindahkan data antara berbilang goroutine dan mencapai pertukaran data yang selamat melalui mekanisme penyegerakan saluran. Terdapat dua jenis saluran: buffered dan unbuffered. Hantar dan terima operasi pada blok saluran tidak buffer sehingga operasi terima dan hantar yang sepadan berlaku. Saluran penimbal boleh mengurangkan perbezaan masa antara operasi hantar dan terima pada tahap tertentu.
Berikut ialah contoh penggunaan saluran penimbal:
package main import ( "fmt" "time" ) func main() { // 创建一个大小为2的带缓冲通道 ch := make(chan string, 2) // 启动两个goroutine go func() { ch <- "Hello" ch <- "World" }() go func() { time.Sleep(time.Second) fmt.Println(<-ch) fmt.Println(<-ch) }() // 等待goroutine执行完毕 time.Sleep(time.Second * 2) }
Dalam contoh di atas, kami mencipta saluran penimbal bersaiz 2. Kemudian dua goroutine dimulakan, satu menghantar dua rentetan ke saluran, dan yang lain menerima dua rentetan dari saluran dan mencetak output. Disebabkan kewujudan penimbal, terdapat perbezaan masa tertentu antara operasi hantar dan terima, tetapi data masih boleh dipindahkan dan disegerakkan melalui saluran.
Selain saluran buffer, golang juga menyokong saluran tidak buffer, yang boleh menjamin penyegerakan antara goroutine dengan lebih tegas.
3. Cara menggunakan goroutine dan saluran untuk mencapai keselarasan
Melalui pengenalan sebelum ini, kita dapat melihat bahawa goroutine dan saluran adalah alat pengaturcaraan serentak yang sangat berguna dalam golang. Di bawah ini kami akan memperkenalkan cara menggunakannya untuk melaksanakan pengaturcaraan serentak melalui beberapa contoh.
1. Muat turun berbilang halaman web secara serentak
Melalui goroutine dan saluran, kami boleh memuat turun berbilang halaman web secara serentak dengan mudah. Contohnya:
package main import ( "fmt" "io/ioutil" "net/http" "time" ) // 下载网页的函数 func download(url string, ch chan<- string) { resp, err := http.Get(url) if err != nil { ch <- fmt.Sprintf("%s error: %v", url, err) return } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { ch <- fmt.Sprintf("%s error: %v", url, err) return } ch <- fmt.Sprintf("%s=%d", url, len(body)) } func main() { // 要下载的网页列表 urls := []string{ "https://www.baidu.com", "https://www.google.com", "https://www.github.com", } // 创建一个无缓冲通道 ch := make(chan string) // 启动多个goroutine下载网页 for _, url := range urls { go download(url, ch) } // 从通道中读取结果,并打印输出 for range urls { fmt.Println(<-ch) } // 等待goroutine执行完毕 time.Sleep(time.Second * 2) }
Dalam contoh di atas, kami menentukan fungsi muat turun untuk memuat turun kandungan web url yang ditentukan dan mengembalikan hasilnya melalui saluran. Kemudian kami memulakan berbilang goroutine melalui gelung for, dan setiap goroutine memanggil fungsi muat turun untuk memuat turun halaman web. Selepas hasil muat turun dikembalikan melalui saluran, ia dibaca dan dicetak dalam goroutine utama. Dengan cara ini, kami boleh memuat turun berbilang halaman web secara serentak dengan mudah dan meningkatkan kecekapan pengendalian dan prestasi program.
2. Memproses berbilang tugas secara serentak
Selain memuat turun halaman web, kami juga boleh menggunakan goroutine dan saluran untuk memproses berbilang tugas secara serentak. Contohnya:
package main import ( "fmt" "math/rand" "time" ) func worker(id int, jobs <-chan int, results chan<- int) { for i := range jobs { fmt.Printf("worker %d start job %d ", id, i) time.Sleep(time.Duration(rand.Intn(3)) * time.Second) fmt.Printf("worker %d finish job %d ", id, i) results <- i * 2 } } func main() { // 定义要处理的任务列表 jobCount := 10 jobs := make(chan int, jobCount) for i := 0; i < jobCount; i++ { jobs <- i } close(jobs) // 定义结果通道 results := make(chan int, jobCount) // 启动多个goroutine处理任务 workerCount := 3 for i := 0; i < workerCount; i++ { go worker(i, jobs, results) } // 从结果通道中读取结果,并打印输出 for j := 0; j < jobCount; j++ { fmt.Println(<-results) } // 等待goroutine执行完毕 time.Sleep(time.Second * 2) }
Dalam contoh di atas, kami menentukan fungsi pekerja untuk mensimulasikan pemprosesan tugas yang ditentukan. Kemudian kami memulakan berbilang goroutine melalui gelung for, setiap goroutine membaca tugasan daripada saluran kerja dan memprosesnya. Hasil pemprosesan dikembalikan melalui saluran keputusan. Akhirnya, semua keputusan dibaca dari saluran keputusan dalam goroutine utama dan dicetak. Dengan cara ini, kami boleh memproses berbilang tugas secara serentak dan meningkatkan kecekapan dan prestasi program berjalan dengan mudah.
4. Ringkasan
Artikel ini memperkenalkan konsep asas pengaturcaraan serentak golang, termasuk penggunaan goroutine dan saluran. Melalui pelbagai contoh, kami menunjukkan cara menggunakan goroutin dan saluran untuk membina program serentak yang cekap. Berbanding dengan bahasa pengaturcaraan lain, model pengaturcaraan serentak golang adalah lebih ringkas dan cekap, yang sangat meningkatkan kecekapan dan prestasi program berjalan. Walau bagaimanapun, perlu diingatkan bahawa menulis program serentak yang berkualiti tinggi bukanlah mudah Ia memerlukan pemahaman dan penguasaan yang mendalam tentang mekanisme dan prinsip pengaturcaraan serentak golang.
Atas ialah kandungan terperinci Golang melaksanakan konkurensi. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!