Belajar! Gunakan saluran buffer sebagai Mutexes

Lepaskan: 2023-08-08 16:21:14
ke hadapan
1363 orang telah melayarinya


Sebagai sebahagian daripada pakej rasmi Go, pakej penyegerakan mempunyai pernyataan berikut:

Pakej penyegerakan menyediakan primitif penyegerakan asas, seperti kunci mutex. Kecuali untuk jenis Once dan WaitGroup, kebanyakan jenis lain ditujukan untuk pustaka fungsi asas. Penyegerakan tahap yang lebih tinggi lebih baik dicapai melalui saluran dan komunikasi

Dalam kebanyakan contoh yang anda boleh temui membenarkan akses serentak, ramai yang menggunakan mutex untuk menyelesaikan masalah. Walau bagaimanapun, terdapat beberapa contoh yang menunjukkan cara menggunakan saluran untuk menyediakan mekanisme penyegerakan. Jadi, mari kita bincangkan dalam artikel ini.

Ciri-ciri kunci mutex

Agar kunci mutex berfungsi, ia perlu dikunci apabila mengakses pembolehubah kongsi, dan ia perlu dibuka kunci selepas operasi selesai. Mutex yang sama tidak dibenarkan dikunci beberapa kali untuk mengelakkan keadaan perlumbaan.

Saluran tidak buffer dan kekurangannya

Jika tiada penerima, penghantar akan menyekat, begitu juga jika tiada penghantar, penerima akan menyekat. Berdasarkan ciri ini, kita tidak boleh menggunakan saluran tidak buffer sebagai kunci.

Mari kita lihat sama ada saluran penimbal boleh digunakan sebagai kunci mutex.

Ciri-ciri dan kelebihan saluran bersaiz buffer 1

Saluran bersaiz buffer 1 mempunyai ciri-ciri berikut: jika buffer penuh, penghantaran akan disekat jika penimbal dikosongkan , penghantaran akan disekat Nyahsekat.

Jelas sekali, ciri menyekat saluran ini adalah wajar Bandingkan dengan ciri mutex:

Apabila penimbal penuh<-->

Buffer dikosongkan<--> ciri melalui kod.

Demonstrasi: Cara menggunakan saluran penimbal sebagai "kunci"

Kami menganggap bahawa terdapat lajur nama yang perlu ditulis pada fail, dan setiap nama perlu ditulis 1000 kali secara berterusan, dan tiada persimpangan nama yang berbeza dibenarkan.

package main
import (
 "errors"
 "fmt"
 "os"
 "sync"
)
func main() {
 file, err := os.Create("record.txt")

 defer func() {
  if err := recover(); err != nil {
   fmt.Printf("Error encounter: %w", err)
  }
  file.Close()
 }()
 if err != nil {
  panic(errors.New("Cannot create/open file"))
 }
 ss := []string{ //string slice literals
  "James",
  "Avery",
  "Peter",
  "John",
  "Beau",
 }
 chanLock := make(chan int, 1) //1
 var wg sync.WaitGroup
 for _, str := range ss { //2
  wg.Add(1) //amended thanks to response from Wang
  //Sheng
  go func(aString string) {

   chanLock <- 1 //3
   for i := 0; i < 1000; i++ {
    file.WriteString(aString + "\n")
   }
   <-chanLock //4
   wg.Done() //5
  }(str) //pass by value
 }
 wg.Wait()
}
Salin selepas log masuk

Dalam kod di atas, //1 kami mencipta saluran dengan penimbal 1. //2 Kami mencipta bilangan goroutin yang sama dengan bilangan nama. //3 bersamaan dengan mengunci, //4 bersamaan dengan membuka kunci, supaya berbilang goroutine boleh menulis nama pada fail record.txt secara serentak, tetapi hanya satu goroutine akan mengendalikan fail pada satu masa.

Perlu diingatkan bahawa kami menggunakan WaitGroup untuk memastikan goroutine utama tidak akan keluar sebelum goroutine kanak-kanak menyelesaikan tugas.

Semoga artikel ini membantu anda, nikmati pengekodan!

Atas ialah kandungan terperinci Belajar! Gunakan saluran buffer sebagai Mutexes. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:Golang菜鸟
Kenyataan Laman Web ini
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
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan