Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Gunakan bahasa Go untuk menyelesaikan masalah keadaan perlumbaan dalam pengaturcaraan serentak

Gunakan bahasa Go untuk menyelesaikan masalah keadaan perlumbaan dalam pengaturcaraan serentak

WBOY
WBOYasal
2023-06-16 08:00:22903semak imbas

Dalam pengaturcaraan serentak, keadaan perlumbaan dianggap sebagai masalah yang sangat menyusahkan. Keadaan perlumbaan bermakna bahawa dua atau lebih utas mengakses sumber yang sama secara serentak, dan sekurang-kurangnya satu daripada mereka cuba mengubah suai sumber, dan susunan baca dan tulis sumber antara utas tidak dapat ditentukan, mengakibatkan keadaan sumber diubah suai. Ketidakkonsistenan telah berlaku. Masalah sedemikian, jika tidak ditangani, akan mempunyai akibat yang tidak dijangka untuk program serentak dan juga menjejaskan ketepatan program. Bahasa Go mempunyai kelebihan unik dalam pengaturcaraan serentak Artikel ini akan memperkenalkan cara bahasa Go menyelesaikan masalah keadaan perlumbaan.

1. Masalah keadaan perlumbaan

Masalah klasik "++" adalah contoh keadaan perlumbaan. Kod berikut:

count := 0
for i := 0; i < 1000; i++ {
   go func() {
      count++
   }()
}
fmt.Println(count)

Dalam contoh ini, kami mencipta 1000 goroutine, dan setiap goroutine akan melakukan operasi kiraan++, dengan itu merealisasikan pengumpulan pembolehubah kiraan. Walau bagaimanapun, jika semua goroutine melakukan operasi ini secara selari dan membaca serta mengubah suai kiraan pembolehubah yang sama pada masa yang berbeza, persaingan data mungkin berlaku kerana susunan setiap goroutine mengubah suai kiraan adalah tidak pasti.

Sudah tentu, kita boleh menyelesaikan masalah ini dengan menggunakan mekanisme seperti mutex, tetapi terdapat penyelesaian yang lebih baik dalam bahasa Go.

2. Gunakan saluran untuk menyelesaikan keadaan perlumbaan

Saluran dalam bahasa Go ialah mekanisme penyegerakan berasaskan mesej. Saluran membenarkan Goroutine yang berbeza berkomunikasi secara langsung dengan menghantar mesej tanpa berkongsi data. Mekanisme ini boleh mengelakkan masalah keadaan perlumbaan yang disebabkan oleh berbilang Goroutines mengakses pembolehubah pada masa yang sama.

Berikut ialah contoh pengumpulan pembolehubah kiraan melalui saluran:

count := 0
ch := make(chan int)
for i := 0; i < 1000; i++ {
   go func() {
      ch <- 1
      }()
}
for i := 0; i < 1000; i++ {
   count += <-ch
}
fmt.Println(count)

Dalam contoh ini, saluran ch dicipta untuk menyegerakkan pelaksanaan setiap goroutine. Setiap kali goroutine melakukan operasi +1 pada pembolehubah kiraan, nilai 1 mesti dihantar ke saluran ch, menunjukkan bahawa operasi +1 telah selesai. Dalam urutan utama, dengan membaca 1000 data dari saluran ch (kerana terdapat 1000 goroutine melakukan pengumpulan pada masa yang sama), dan kemudian mengumpul data ini, anda boleh mendapatkan hasil akhir.

3. Gunakan pakej atom untuk menyelesaikan keadaan perlumbaan

Pakej atom dalam bahasa Go menyediakan satu set fungsi untuk operasi atom pada jenis data asas. Fungsi ini dijamin bebas daripada keadaan perlumbaan kerana ia menggunakan primitif perkakasan peringkat rendah untuk melaksanakan semua operasi. Operasi atom yang disediakan oleh bahasa Go ini boleh menggantikan beberapa mekanisme penyegerakan tradisional, seperti kunci mutex.

Berikut ialah contoh mengumpul pembolehubah kiraan dengan menggunakan fungsi atomic.AddInt32() dalam pakej atom:

count := int32(0)
var wg sync.WaitGroup
for i := 0; i < 1000; i++ {
   wg.Add(1)
   go func() {
      atomic.AddInt32(&count, 1)
      wg.Done()
   }()
}
wg.Wait()
fmt.Println(count)

Dalam contoh ini, kami menggunakan kiraan pembolehubah jenis int32 dan Tetapkan nilai awalnya kepada 0. Kemudian tunggu 1000 goroutine dilaksanakan melalui penyegerakan.WaitGroup sebelum mengeluarkan nilai kiraan akhir. Fungsi AddInt32() dalam pakej atom digunakan di sini untuk mengumpul pembolehubah kiraan Fungsi ini boleh memastikan pelaksanaan atom operasi +1 dan mengelakkan masalah keadaan perlumbaan operasi membaca dan menulis serentak pada pembolehubah.

4. Ringkasan

Dalam bahasa Go, sangat berkesan untuk menggunakan saluran dan pakej atom untuk menyelesaikan masalah keadaan perlumbaan. Jika mekanisme ini boleh digunakan dengan mahir, masalah penyegerakan yang biasa dalam banyak bahasa lain boleh dielakkan dan aplikasi serentak yang cekap, mantap dan boleh dipercayai boleh dicapai. Ia layak untuk kajian dan penguasaan kami yang mendalam.

Atas ialah kandungan terperinci Gunakan bahasa Go untuk menyelesaikan masalah keadaan perlumbaan dalam pengaturcaraan serentak. 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