Biasa dengan mekanisme kunci dan mutex dalam bahasa Go

WBOY
Lepaskan: 2024-03-27 08:33:03
asal
1013 orang telah melayarinya

熟悉 Go 语言中的锁和互斥机制

Bahasa Go ialah bahasa pengaturcaraan yang sangat popular, terutamanya dalam pengaturcaraan serentak. Dan apabila kita berurusan dengan pengaturcaraan serentak, kunci dan mekanisme pengecualian bersama tidak dapat dielakkan. Artikel ini akan memperkenalkan mekanisme kunci dan pengecualian bersama dalam bahasa Go.

1. Mutex lock

Mutex lock ialah mekanisme penguncian paling asas dan juga digunakan secara meluas dalam bahasa Go. Dalam sesetengah kes, berbilang goroutine boleh mengakses pembolehubah yang dikongsi pada masa yang sama Dalam kes ini, kita perlu menggunakan kunci mutex untuk menyekat hanya satu goroutine daripada mengakses pembolehubah yang dikongsi pada masa yang sama.

Dalam bahasa Go, penggunaan mutex lock adalah sangat mudah Kita hanya perlu menambah mutex.Lock() dan mutex.Unlock(), dengan mutex ialah pembolehubah jenis <code>sync.Mutex. mutex.Lock()mutex.Unlock() 即可,其中 mutex 是一个 sync.Mutex 类型的变量。

在下面的示例代码中,我们模拟了多个 goroutine 同时访问一个共享变量,这时候,互斥锁可以保证同一时刻只有一个 goroutine 能够修改变量值。

package main

import (
    "fmt"
    "sync"
)

var count int
var mutex sync.Mutex

func main() {
    for i := 0; i < 10; i++ {
        go increment()
    }
    fmt.Scanln()
}

func increment() {
    for i := 0; i < 10000; i++ {
        mutex.Lock()
        count++
        mutex.Unlock()
    }
}
Salin selepas log masuk

二、读写锁

在上面的示例中,我们采用互斥锁来限制共享变量的访问。但是,在某些情况下,读操作比写操作更加频繁,这时候,使用互斥锁会导致读取性能下降,因为互斥锁会阻塞其他 goroutine 的读和写操作。

为了解决这个问题,Go 语言提供了一种特殊的锁机制,叫做读写锁。读写锁可以同时支持多个 goroutine 进行读操作,但是在写操作进行的时候,必须排斥所有的读和写操作。

在 Go 语言中,读写锁的使用也非常简单。我们只需要在需要保护的代码段前后分别加上 rwlock.RLock()rwlock.RUnlock() 用于读操作,加上 rwlock.Lock()rwlock.Unlock() 用于写操作。其中 rwlock 是一个 sync.RWMutex 类型的变量。

下面的示例演示了多个 goroutine 同时读取一个共享变量的情况,我们使用了读写锁来保证高效的读取操作。

package main

import (
    "fmt"
    "sync"
)

var count int
var rwlock sync.RWMutex

func main() {
    for i := 0; i < 10; i++ {
        go read()
    }
    fmt.Scanln()
}

func read() {
    for i := 0; i < 10000; i++ {
        rwlock.RLock()
        fmt.Println(count)
        rwlock.RUnlock()
    }
}
Salin selepas log masuk

三、原子操作

在某些情况下,我们只需要进行简单的加减操作,这时候可以通过原子操作来实现。原子操作可以保证这些简单的操作在多个 goroutine 中的执行顺序是稳定的,从而避免了出现竞态条件。

在 Go 语言中,原子操作可以通过 sync/atomic 包中的一些函数来实现。例如,atomic.AddInt32(&count, 1)

Dalam kod sampel di bawah, kami mensimulasikan berbilang goroutin mengakses pembolehubah dikongsi pada masa yang sama Pada masa ini, kunci mutex boleh memastikan bahawa hanya satu goroutine boleh mengubah suai nilai pembolehubah pada masa yang sama.

package main

import (
    "fmt"
    "sync/atomic"
)

var count int32

func main() {
    for i := 0; i < 10; i++ {
        go increment()
    }
    fmt.Scanln()
}

func increment() {
    for i := 0; i < 10000; i++ {
        atomic.AddInt32(&count, 1)
    }
}
Salin selepas log masuk
2. Kunci baca-tulis

Dalam contoh di atas, kami menggunakan kunci mutex untuk menyekat akses kepada pembolehubah kongsi. Walau bagaimanapun, dalam beberapa kes, operasi baca lebih kerap daripada operasi tulis Dalam kes ini, menggunakan kunci mutex akan menyebabkan prestasi bacaan berkurangan kerana kunci mutex akan menyekat operasi baca dan tulis goroutine yang lain. 🎜🎜Untuk menyelesaikan masalah ini, bahasa Go menyediakan mekanisme kunci khas yang dipanggil kunci baca-tulis. Kunci baca-tulis boleh menyokong berbilang goroutin untuk operasi baca pada masa yang sama, tetapi apabila operasi tulis sedang dijalankan, semua operasi baca dan tulis mesti dikecualikan. 🎜🎜Dalam bahasa Go, penggunaan kunci baca-tulis juga sangat mudah. Kami hanya perlu menambah rwlock.RLock() dan rwlock.RUnlock() sebelum dan selepas segmen kod yang perlu dilindungi untuk operasi baca dan tambah rwlock. Lock() dan rwlock.Unlock() digunakan untuk operasi tulis. Di mana rwlock ialah pembolehubah jenis sync.RWMutex. 🎜🎜Contoh berikut menunjukkan situasi di mana berbilang goroutin membaca pembolehubah dikongsi pada masa yang sama Kami menggunakan kunci baca-tulis untuk memastikan operasi baca yang cekap. 🎜rrreee🎜3. Operasi atom🎜🎜Dalam sesetengah kes, kita hanya perlu melakukan operasi tambah dan tolak yang mudah, yang boleh dicapai melalui operasi atom. Operasi atom boleh memastikan bahawa susunan pelaksanaan operasi mudah ini dalam berbilang goroutine adalah stabil, sekali gus mengelakkan keadaan perlumbaan. 🎜🎜Dalam bahasa Go, operasi atom boleh dilaksanakan melalui beberapa fungsi dalam pakej sync/atomic. Contohnya, atomic.AddInt32(&count, 1) Fungsi ini boleh menambah 1 pada pembolehubah kiraan melalui penambahan atom. 🎜🎜Contoh berikut menunjukkan cara menggunakan operasi atom untuk meningkatkan nilai pembolehubah dalam berbilang goroutin dengan selamat. 🎜rrreee🎜Ringkasnya, bahasa Go menyediakan pelbagai mekanisme kunci dan pengecualian bersama untuk melindungi akses kepada pembolehubah yang dikongsi, dan juga menyokong operasi atom untuk mengelakkan keadaan perlumbaan. Adalah sangat penting bagi pembangun bahasa Go untuk membiasakan diri dengan penggunaan mekanisme ini. 🎜

Atas ialah kandungan terperinci Biasa dengan mekanisme kunci dan mutex dalam bahasa Go. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:php.cn
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
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!