Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Belajar! Gunakan saluran buffer sebagai Mutexes

Belajar! Gunakan saluran buffer sebagai Mutexes

Golang菜鸟
Golang菜鸟ke hadapan
2023-08-08 16:21:141323semak imbas


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 penuh71fb34173e4ee87dab1f85dc1c283a44

Buffer dikosongkan71fb34173e4ee87dab1f85dc1c283a44 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()
}

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!

Kenyataan:
Artikel ini dikembalikan pada:Golang菜鸟. Jika ada pelanggaran, sila hubungi admin@php.cn Padam