Rumah >pembangunan bahagian belakang >Golang >Artikel yang menerangkan mekanisme kunci dalam bahasa Go secara terperinci

Artikel yang menerangkan mekanisme kunci dalam bahasa Go secara terperinci

PHPz
PHPzasal
2023-04-13 18:12:031680semak imbas

Sebagai bahasa pengaturcaraan serentak, mekanisme kawalan serentak bahasa Go adalah sangat penting. Salah satu mekanisme yang paling biasa digunakan ialah mekanisme kunci. Artikel ini akan memperkenalkan cara melaksanakan mekanisme kunci dalam bahasa Go.

Kunci bahasa Go

Dalam bahasa Go, kunci yang paling biasa digunakan ialah mutex (Mutex). Mutex ialah semafor binari khas yang digunakan untuk mengawal akses kepada sumber yang dikongsi. Bahasa Go menyediakan fungsi kunci mutex melalui pakej "segerak" dalam perpustakaan standard. Jenis kunci mutex ditakrifkan seperti berikut:

type Mutex struct {
    state int32
    sema  uint32
}

Medan keadaan digunakan untuk merekod status kunci, dan medan sema ialah semaphore.

Sebelum menggunakan kunci mutex, anda perlu mendapatkan kunci dengan memanggil kaedah Kunci. Jika kunci sudah dipegang oleh coroutine lain, coroutine semasa akan disekat, menunggu kunci dilepaskan. Contohnya:

var mu sync.Mutex
// ...
mu.Lock()
// ...
mu.Unlock()

Dalam kod ini, mu ialah kunci mutex. mu.Lock() digunakan untuk memperoleh kunci Jika kunci sudah dipegang oleh coroutine lain, coroutine semasa akan disekat. mu.Unlock() digunakan untuk melepaskan kunci.

Mekanisme ini sangat mudah, tetapi sebenarnya tidak begitu cekap. Jika terdapat banyak coroutine yang cuba memperoleh mutex yang sama, kesesakan akan mudah berlaku semasa pemprosesan, sekali gus mengurangkan kecekapan keseluruhan program.

Kunci baca-tulis

Dalam sesetengah senario yang memerlukan operasi baca dan tulis, kecekapan kunci mutex adalah sangat rendah. Oleh kerana kunci mutex hanya boleh menjamin bahawa hanya satu coroutine boleh mengakses sumber yang dikongsi pada masa yang sama, kedua-dua operasi baca dan tulis perlu menunggu kunci dikeluarkan terlebih dahulu. Walau bagaimanapun, jika terdapat hanya operasi baca, penantian ini tidak diperlukan. Kerana berbilang coroutine boleh membaca sumber yang sama pada masa yang sama tanpa menyebabkan pengubahsuaian yang merosakkan data.

Pada masa ini, anda perlu menggunakan kunci baca-tulis (RWMutex). Kunci baca-tulis ialah jenis kunci pengecualian bersama yang istimewa. Sumber boleh dibaca oleh berbilang coroutine pada masa yang sama, tetapi hanya boleh ditulis oleh satu coroutine. Oleh itu, semasa operasi tulis, semua operasi baca akan disekat, menunggu operasi tulis selesai. Jenis kunci baca-tulis ditakrifkan seperti berikut:

type RWMutex struct {
    w           Mutex // 用于写操作的互斥锁
    writerSem   uint32
    readerSem   uint32
    readerCount int32  // 当前进行读操作的协程数量
    readerWait  int32  // 等待读操作的协程数量
}

Kunci baca-tulis mempunyai dua keadaan: kunci baca dan kunci tulis. Dalam keadaan kunci baca, berbilang coroutine boleh melakukan operasi baca pada masa yang sama; dalam keadaan kunci tulis, hanya satu coroutine boleh melakukan operasi tulis. Pada masa yang sama, kunci baca-tulis menyokong mekanisme keutamaan coroutine, yang bermaksud bahawa coroutine yang menunggu lebih lama akan memperoleh kunci terlebih dahulu.

Kaedah untuk memperoleh kunci baca ialah RLock(), dan kaedah untuk melepaskan kunci baca ialah RUnlock(); kaedah untuk memperoleh kunci tulis ialah Lock(), dan kaedah untuk melepaskan tulis kunci ialah Unlock(). Contohnya:

var rw sync.RWMutex
// ...
func read() {
    rw.RLock()
    // ...
    rw.RUnlock()
}
// ...
func write() {
    rw.Lock()
    // ...
    rw.Unlock()
}

Kod ini menunjukkan cara menggunakan kunci baca-tulis dalam bahasa Go. Fungsi read() memperoleh kunci baca dan boleh dipanggil oleh berbilang coroutine pada masa yang sama manakala fungsi write() memperoleh kunci tulis dan hanya boleh dipanggil oleh satu coroutine pada masa yang sama.

segerakkan.Sekali

segerakkan.Once ialah kunci yang sangat berguna. Ia hanya melakukan operasi pemula sekali. Terdapat nilai Boolean di dalam Once Jika ia dikunci, apabila panggilan gagal, panggilan berikutnya akan kembali serta-merta dan permulaan tidak akan dilaksanakan semula.

func singleton() {
    var once sync.Once
    once.Do(func() {
        // 初始化对象
    })
    // 使用对象
}

Menggunakan penyegerakan.Sekali boleh mengelakkan operasi pemulaan berulang dalam berbilang coroutine.

Ringkasan

Dalam bahasa Go, mekanisme untuk melaksanakan kawalan serentak berbilang benang adalah sangat penting. Dengan menggunakan mekanisme seperti kunci mutex, kunci baca-tulis dan Sekali, program boleh menjadi lebih cekap dan lebih selamat apabila mengendalikan operasi serentak. Dalam amalan, pelbagai mekanisme perlu dipilih mengikut senario tertentu, dan ujian dan pengesahan tertentu perlu dijalankan sebelum pemilihan dan penggunaan.

Atas ialah kandungan terperinci Artikel yang menerangkan mekanisme kunci dalam bahasa Go secara terperinci. 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