Dengan peningkatan prestasi perkakasan komputer, semakin banyak aplikasi perlu mengendalikan sejumlah besar tugas serentak dan tak segerak. Ini menimbulkan persoalan: Bagaimana untuk mengendalikan tugas-tugas ini dengan cekap dan memastikan kualiti kod? Bahasa Go mempunyai keupayaan sedia ada untuk menyokong pengaturcaraan serentak dan tak segerak Artikel ini akan memperkenalkan cara terbaik untuk melaksanakan pengaturcaraan serentak dan tak segerak menggunakan bahasa Go.
1 Memahami model pengaturcaraan serentak dan tak segerak bagi bahasa Go
Model pengaturcaraan serentak dan tak segerak bagi bahasa Go dilaksanakan berdasarkan goroutine dan saluran. Goroutine ialah benang ringan yang boleh menjalankan berbilang tugas serentak dalam program. Saluran adalah saluran komunikasi antara goroutine, yang boleh merealisasikan penghantaran data antara goroutine yang berbeza.
Dalam bahasa Go, goroutine baharu boleh dimulakan dengan menggunakan kata kunci go. Seperti yang ditunjukkan di bawah:
go func() { // do something }()
Dalam kod di atas, func() mewakili kod fungsi yang akan dilaksanakan. Memulakan fungsi ini dengan kata kunci go akan melaksanakannya dalam goroutine baharu.
Dalam bahasa Go, model CSP (Communicating Sequential Processes) diguna pakai, yang bermaksud konkurensi dan kerjasama dijalankan melalui saluran. Saluran mempunyai dua titik akhir: hantar dan terima. Komunikasi antara goroutine boleh dicapai dengan menghantar dan menerima saluran.
2. Cara membuat dan menggunakan saluran
Dalam bahasa Go, buat saluran melalui fungsi make. Berikut adalah untuk mencipta saluran jenis rentetan:
ch := make(chan string)
Gunakan simbol <-untuk menghantar data ke saluran:
ch <- "Hello world"
Gunakan simbol <-untuk menerima data daripada saluran:
msg := <-ch
Nota: Jika tiada data untuk diterima, program akan menyekat dalam operasi penerimaan. Begitu juga, jika saluran penuh, operasi hantar akan disekat.
Terdapat juga kata kunci pilih dalam bahasa Go yang boleh digunakan untuk memilih pelaksanaan goroutine. Pilih boleh mengandungi berbilang kes, setiap kes ialah operasi terima atau hantar saluran. Apabila pilih dilaksanakan, ia akan secara rawak memilih kes yang tersedia untuk pelaksanaan Jika tiada kes tersedia, ia akan disekat.
Berikut ialah contoh:
ch1 := make(chan int) ch2 := make(chan int) go func() { for i := 0; i < 10; i++ { ch1 <- i } }() go func() { for i := 0; i < 10; i++ { ch2 <- i } }() for i := 0; i < 20; i++ { select { case v := <-ch1: fmt.Println("ch1:", v) case v := <-ch2: fmt.Println("ch2:", v) } }
Dalam contoh di atas, kami mencipta dua goroutine, satu menghantar data ke ch1 dan satu lagi menghantar data ke ch2. Kemudian gunakan pernyataan pilih dalam goroutine utama untuk memantau data ch1 dan ch2. Apabila data tersedia, pernyataan kes yang sepadan dilaksanakan.
3. Gunakan WaitGroup untuk mengawal pelaksanaan goroutine
Biasanya, kita perlu menunggu semua pelaksanaan goroutine selesai sebelum melakukan operasi lain. Anda boleh menggunakan WaitGroup dalam pakej penyegerakan untuk mencapai keperluan ini. WaitGroup boleh digunakan untuk menunggu sekumpulan goroutine selesai.
Berikut ialah contoh:
var wg sync.WaitGroup func main() { for i := 0; i < 10; i++ { wg.Add(1) go func() { defer wg.Done() // do something }() } wg.Wait() // All goroutines are done }
Dalam contoh di atas, kami mencipta 10 goroutine dan memanggil kaedah Tambah dalam WaitGroup menunjukkan bahawa 10 goroutine akan dilaksanakan. Kemudian gunakan defer stmt.Done() dalam setiap goroutine untuk memberitahu WaitGroup bahawa goroutine telah selesai. Akhir sekali, kaedah Tunggu dipanggil dalam goroutine utama untuk menunggu semua goroutine menyelesaikan pelaksanaan.
4 Gunakan penyegerakan.Mutex untuk memastikan keselamatan data
Dalam bahasa Go, jika pembolehubah akan diakses oleh berbilang goroutine pada masa yang sama, maka anda perlu menggunakan kunci untuk memastikan data keselamatan. Kunci boleh dilaksanakan menggunakan Mutex daripada pakej penyegerakan.
Berikut ialah contoh:
var mu sync.Mutex var count int func inc() { mu.Lock() defer mu.Unlock() count++ } func main() { for i := 0; i < 10; i++ { go inc() } time.Sleep(time.Second) fmt.Println("count:", count) }
Dalam contoh di atas, kami mencipta objek .Mutex untuk memastikan akses kepada pengiraan selamat untuk benang. Dalam fungsi inc, kita mula-mula memperoleh kunci dan kemudian melepaskan kunci dalam penangguhan. Dalam fungsi utama, kami memulakan 10 inc goroutine untuk mengakses kiraan.
5 Gunakan pakej konteks untuk mengendalikan tamat masa dan pembatalan
Dalam bahasa Go, kami boleh menggunakan pakej konteks untuk mengendalikan tamat masa dan pembatalan untuk mengelakkan kebocoran goroutine dan pembaziran sumber. Konteks boleh menetapkan tarikh akhir dan membatalkan isyarat Semua goroutine akan dibatalkan apabila isyarat dicetuskan.
Berikut ialah contoh:
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) defer cancel() ch := make(chan int) go func() { time.Sleep(time.Second * 5) ch <- 1 }() select { case <-ch: fmt.Println("received") case <-ctx.Done(): fmt.Println("timeout or cancelled") }
Dalam contoh di atas, kami menggunakan fungsi context.WithTimeout untuk mencipta objek Konteks dengan tamat masa 3 saat dan mulakan goroutine untuk menunggu 5 saat. Dalam pernyataan pilih, jika goroutine selesai dalam masa 3 saat, cetak "diterima", jika tidak cetak "tamat masa atau dibatalkan".
6. Ringkasan
Pengaturcaraan serentak dan tak segerak boleh dilaksanakan dengan mudah menggunakan bahasa Go. Dengan menggunakan goroutine dan saluran, kami boleh membina model konkurensi yang cekap. Pada masa yang sama, menggunakan WaitGroup, Mutex dan Context boleh menjadikan program kami lebih selamat dan lebih mantap.
Sudah tentu, jika digunakan secara tidak wajar, konkurensi tinggi dan pengaturcaraan tak segerak juga boleh menyebabkan beberapa masalah, seperti keadaan perlumbaan, kebuntuan, kelaparan dan masalah lain. Oleh itu, apabila menggunakan pengaturcaraan serentak dan tak segerak, pastikan anda memberi perhatian kepada kualiti dan ketepatan kod.
Atas ialah kandungan terperinci Cara terbaik untuk melaksanakan pengaturcaraan serentak dan tak segerak menggunakan bahasa Go. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!