Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Kaji pelaksanaan kunci Golang

Kaji pelaksanaan kunci Golang

PHPz
PHPzasal
2023-12-28 10:32:43665semak imbas

Kaji pelaksanaan kunci Golang

Meneroka mekanisme pelaksanaan kunci Golang

Pengenalan:

Dalam pengaturcaraan serentak, kunci (Kunci) ialah mekanisme penyegerakan yang biasa digunakan untuk melindungi akses kepada sumber yang dikongsi. Sebagai bahasa pengaturcaraan dengan prestasi konkurensi tinggi dan sintaks ringkas, Golang menyediakan banyak mekanisme kunci, termasuk mutex (Mutex), kunci baca-tulis (RWMutex), dll. Artikel ini akan menyelidiki mekanisme pelaksanaan kunci Golang dan menunjukkannya melalui contoh kod tertentu.

1. Mekanisme pelaksanaan kunci mutex (Mutex)

  1. Pelaksanaan kaedah kunci:

Mekanisme pelaksanaan kunci mutex terutamanya terdiri daripada tiga komponen penting: barisan menunggu, bendera status dan operasi atom. Apabila benang cuba memperoleh kunci mutex, ia akan menyemak bendera status terlebih dahulu Jika bendera status dikunci, ia akan menambah dirinya pada baris gilir menunggu dan berputar untuk menunggu. Jika bendera status dibuka kunci, cuba gunakan operasi atom untuk memperoleh kunci dan tetapkan bendera status kepada terkunci. Berikut ialah contoh kod khusus kunci mutex:

type Mutex struct {
    waiting   int32 // 等待队列,记录等待获取锁的goroutine数量
    isLocked  int32 // 锁的状态标志,0代表未锁住,1代表已锁住
}

func (m *Mutex) Lock() {
    for !atomic.CompareAndSwapInt32(&m.isLocked, 0, 1) { // 自旋等待获取锁
        runtime.Gosched()
    }
}

func (m *Mutex) Unlock() {
    atomic.StoreInt32(&m.isLocked, 0) // 释放锁,将状态标志设置为未锁住
}
  1. Pelaksanaan operasi atom:

Kod di atas menggunakan fungsi CompareAndSwapInt32 dan StoreInt32 dalam pakej atom untuk melaksanakan operasi atom. Fungsi CompareAndSwapInt32 digunakan untuk operasi perbandingan dan pertukaran Jika bendera status kunci dibuka, ia ditetapkan kepada dikunci dan kembali benar jika bendera status kunci dikunci, ia akan kembali palsu. Fungsi StoreInt32 digunakan untuk menetapkan bendera status secara atom untuk dibuka kunci. Operasi atom ini boleh mengelakkan berlakunya keadaan perlumbaan dengan berkesan dan memastikan ketepatan kunci.

2. Mekanisme pelaksanaan kunci baca-tulis (RWMutex)

  1. Mekanisme pelaksanaan kunci tulis:

Kunci baca-tulis ialah mekanisme kunci khas yang membenarkan berbilang gorout membaca sumber yang dikongsi pada masa yang sama, tetapi hanya Sebuah goroutine menulis kepada sumber yang dikongsi. Mekanisme pelaksanaan kunci tulis adalah serupa dengan kunci mutex, tetapi terdapat beberapa perbezaan. Berikut ialah contoh kod khusus kunci tulis:

type RWMutex struct {
    writerSem uint32    // 写入信号量,用于限制只能有一个goroutine写入
    readerSem uint32    // 读取信号量,用于限制多个goroutine同时读取
    readerCount int32   // 读取计数,记录当前同时读取的goroutine数量
    readerWait  int32   // 当前等待读取的goroutine数量
}

func (rw *RWMutex) Lock() {
    rw.lockWhile(func() {atomic.LoadUint32(&rw.readerSem) != 0 || atomic.LoadUint32(&rw.writerSem) != 0})
    atomic.AddUint32(&rw.writerSem, 1) // 获取写锁,递增写入信号量
}

func (rw *RWMutex) Unlock() {
    atomic.AddUint32(&rw.writerSem, ^uint32(0)) // 释放写锁,递减写入信号量
    rw.unlockWhile(func() {atomic.LoadInt32(&rw.readerCount) != 0}) // 释放读锁,根据读取计数判断是否需要唤醒等待读取的goroutine
}
  1. Mekanisme pelaksanaan kunci baca:

Mekanisme pelaksanaan kunci baca dilaksanakan terutamanya dengan menambah semaphore baca dan kiraan baca Apabila goroutine memperoleh kunci baca , ia akan mula-mula menyemak sama ada semaphore tulis adalah sifar dan tiada goroutin lain menunggu untuk ditulis. Jika ya, tambahkan kiraan baca dan dapatkan kunci baca jika tidak, tambahkan dirinya pada baris gilir menunggu untuk menunggu putaran. Berikut ialah contoh kod khusus kunci baca:

func (rw *RWMutex) RLock() {
    rw.lockWhile(func() {atomic.LoadUint32(&rw.writerSem) != 0}) // 当有 goroutine 持有写锁时,自旋等待
    atomic.AddInt32(&rw.readerCount, 1) // 递增读取计数
}

func (rw *RWMutex) RUnlock() {
    atomic.AddInt32(&rw.readerCount, -1) // 递减读取计数
    rw.unlockWhile(func() {atomic.LoadInt32(&rw.readerCount) != 0}) // 根据读取计数判断是否需要唤醒等待读取的goroutine
}
  1. Bangun goroutine yang menunggu:

Dalam pelaksanaan kunci baca dan tulis, terdapat operasi untuk membangunkan goroutine yang menunggu. Ia dilaksanakan melalui dua fungsi tambahan: lockWhile dan unlockWhile. Fungsi lockWhile digunakan untuk menunggu putaran Apabila keadaan yang diberikan adalah benar, goroutine akan disekat sehingga syarat itu dipenuhi; kunci. Ini memastikan bahawa goroutine menunggu kunci boleh dibangkitkan tepat pada masanya dan meningkatkan prestasi serentak.

Ringkasan:

Dalam artikel ini, kami menjalankan penerokaan mendalam tentang mekanisme pelaksanaan kunci di Golang dan menunjukkannya melalui contoh kod khusus. Kunci Mutex dilaksanakan melalui baris gilir menunggu dan bendera status untuk memastikan bahawa hanya satu goroutine boleh memegang kunci manakala kunci baca-tulis dilaksanakan melalui semaphore tulis, baca semaphore dan kiraan baca, membolehkan berbilang goroutine membaca dan menulis pada masa yang sama. Hanya satu goroutine dibenarkan menulis. Mekanisme kunci ini memastikan akses selamat kepada sumber yang dikongsi dan meningkatkan prestasi program serentak melalui operasi atom dan menunggu bersyarat.

Atas ialah kandungan terperinci Kaji pelaksanaan kunci Golang. 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