Dalam pengaturcaraan golang, kunci adalah mekanisme penting untuk mengawal konkurensi. Walau bagaimanapun, penguncian tidak diperlukan dalam semua kes Dalam sesetengah kes, penguncian akan meningkatkan kerumitan kod dan menjejaskan prestasi.
Jadi, dalam keadaan apakah kunci perlu dikunci dalam pengaturcaraan golang?
Apabila berbilang goroutin menulis kepada pembolehubah yang sama pada masa yang sama, ia perlu dikunci. Ini kerana penyegerakan dalam golang diselesaikan melalui mekanisme saluran dan kunci. Jika kunci tidak dikunci, keadaan perlumbaan mungkin berlaku, mengakibatkan ketidakkonsistenan data.
Contohnya:
var count int func addCount(value int) { count += value }
Dalam contoh ini, jika berbilang goroutin memanggil fungsi addCount
pada masa yang sama, nilai count
akan menjadi salah.
Untuk menyelesaikan masalah ini, anda boleh menggunakan jenis sync.Mutex
untuk mengunci, contohnya:
var count int var mu sync.Mutex func addCount(value int) { mu.Lock() defer mu.Unlock() count += value }
Dalam contoh ini, gunakan mu.Lock()
untuk mengunci count
untuk memastikan bahawa setiap Goroutine secara eksklusif boleh menduduki pembolehubah semasa menjalankan operasi.
Apabila berbilang goroutin melakukan operasi baca dan tulis, penguncian juga diperlukan. Ini kerana dalam golang, membaca dan menulis adalah kedua-dua operasi atom, tetapi mungkin terdapat pertindihan antara operasi membaca dan menulis, menyebabkan data tidak konsisten.
Contohnya:
var m map[int]string func writeToMap(key int, value string) { m[key] = value } func readFromMap(key int) string { return m[key] }
Dalam contoh ini, jika berbilang goroutin membaca dan menulis kepada map
pada masa yang sama, ia akan menyebabkan keadaan perlumbaan, mengakibatkan ketidakkonsistenan data .
Untuk menyelesaikan masalah ini, anda boleh menggunakan jenis sync.RWMutex
untuk mengunci, contohnya:
var m map[int]string var mu sync.RWMutex func writeToMap(key int, value string) { mu.Lock() defer mu.Unlock() m[key] = value } func readFromMap(key int) string { mu.RLock() defer mu.RUnlock() return m[key] }
Dalam contoh ini, gunakan mu.RLock()
dan mu.RUnlock()
untuk membaca dan menulis masing-masing.
Apabila penyegerakan diperlukan antara berbilang goroutin, penguncian juga diperlukan. Saluran sering digunakan dalam golang untuk menyegerakkan antara gorouti, tetapi apabila saluran tidak berkenaan, mekanisme kunci perlu digunakan.
Contohnya:
var wg sync.WaitGroup var mu sync.Mutex var data []int func worker() { defer wg.Done() for i := 0; i < 1000; i++ { mu.Lock() data = append(data, i) mu.Unlock() } } func main() { for i := 0; i < 10; i++ { wg.Add(1) go worker() } wg.Wait() fmt.Println(data)
Dalam contoh ini, 10 goroutin menambah 1000 integer kepada data
pada masa yang sama. Memandangkan data
ialah pembolehubah kongsi, anda perlu menggunakan sync.Mutex
untuk menguncinya.
Ringkasnya, dalam pengaturcaraan golang, situasi di mana kunci perlu digunakan termasuk situasi di mana berbilang gorouti mengakses pembolehubah kongsi, berbilang gorouti melakukan operasi baca dan tulis, dan penyegerakan diperlukan antara berbilang gorouti. Apabila menggunakan kunci, anda perlu memilih jenis kunci yang sesuai mengikut situasi sebenar untuk memastikan ketepatan dan prestasi program.
Atas ialah kandungan terperinci Di manakah golang perlu dikunci?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!