Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Di manakah golang perlu dikunci?

Di manakah golang perlu dikunci?

PHPz
PHPzasal
2023-04-25 15:10:44828semak imbas

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?

  1. Berbilang goroutin mengakses pembolehubah kongsi

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.

  1. Berbilang goroutin melakukan operasi baca dan tulis

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.

  1. Penyegerakan antara berbilang goroutin

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!

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