Penjelasan terperinci tentang ciri bahasa Golang: keselamatan serentak dan mekanisme penguncian

王林
Lepaskan: 2023-07-18 14:15:23
asal
1635 orang telah melayarinya

Penjelasan terperinci tentang ciri bahasa Golang: Keselamatan konkurensi dan mekanisme kunci

Pengenalan:
Dengan perkembangan pesat Internet, semakin banyak aplikasi perlu memproses berbilang tugas secara selari. Disebabkan kekhususan pengaturcaraan serentak, masalah seperti keadaan perlumbaan dan kebuntuan mungkin berlaku dalam program. Untuk menyelesaikan masalah ini, Golang menyediakan ciri pengaturcaraan serentak yang kaya dan mekanisme kunci. Artikel ini akan menyelidiki keselamatan serentak dan mekanisme kunci dalam bahasa Golang dan menerangkannya secara terperinci melalui contoh kod.

1. Keselamatan Concurrency
Keselamatan Concurrency bermakna apabila berbilang rangkaian mengakses sumber dikongsi pada masa yang sama, tidak akan ada keputusan yang tidak pasti atau keadaan perlumbaan. Golang melaksanakan keselamatan serentak melalui penggunaan goroutin dan Saluran.

1.1 Goroutine
Goroutine ialah konsep utas ringan di Golang Berbanding dengan utas tradisional, goroutine mempunyai kos permulaan dan penjadualan yang lebih rendah Apabila menulis kod serentak, tidak perlu membuat utas secara manual, hanya gunakan kata kunci go boleh dibuat. Berikut ialah contoh mudah:

package main

import "fmt"

func printHelloWorld() {
    fmt.Println("Hello World")
}

func main() {
    go printHelloWorld()
    fmt.Println("Main Function")
}
Salin selepas log masuk

Dalam kod di atas, kami telah mencipta goroutine bernama printHelloWorld dalam fungsi utama menggunakan kata kunci go. Apabila utas utama melaksanakan pernyataan go, atur cara akan serta-merta mencipta goroutine baharu untuk melaksanakan fungsi printHelloWorld, dan utas utama akan terus melaksanakan kod berikut, jadi hasil output mungkin "Hello World" diikuti dengan "Fungsi Utama ". Ia juga mungkin hasil silang daripada kedua-duanya.

1.2 Saluran
Saluran ialah mekanisme yang digunakan untuk komunikasi antara gorouti di Golang. Melalui Saluran, kami boleh menghantar data dengan selamat antara gorouti yang berbeza. Saluran menyediakan dua mod: penyegerakan dan penimbalan.

Saluran dalam blok mod segerak menghantar dan menerima operasi sehingga hujung satu lagi bersedia. Contohnya:

package main

import "fmt"

func sendMessage(ch chan string, msg string) {
    ch <- msg
}

func main() {
    msgChan := make(chan string)
    go sendMessage(msgChan, "Hello World")
    msg := <- msgChan
    fmt.Println(msg)
}
Salin selepas log masuk

Dalam kod di atas, kami mencipta Saluran segerak bernama msgChan dan menghantar mesej "Hello World" ke Saluran dalam goroutine, dalam urutan utama melalui msg := <- msgChan Terima dan cetak mesej daripada Saluran.

Saluran dalam mod penimbal membolehkan penimbalan beberapa mesej semasa operasi penghantaran tanpa menyekat Operasi penghantaran hanya akan disekat apabila mesej dalam Saluran penuh. Contohnya:

package main

import "fmt"

func main() {
    msgChan := make(chan string, 2)
    msgChan <- "Hello"
    msgChan <- "World"
    fmt.Println(<-msgChan)
    fmt.Println(<-msgChan)
}
Salin selepas log masuk

Dalam kod di atas, kami mencipta Saluran penimbal dengan saiz 2, menghantar dua mesej "Hello" dan "World" masing-masing dan menerima serta mencetak daripada Saluran melalui dua maklumat operasi <-msgChan.

2. Mekanisme Penguncian
Selain ciri goroutine dan Saluran, Golang juga menyediakan mekanisme penguncian yang kaya untuk menyelesaikan keadaan perlumbaan dan masalah kebuntuan dalam pengaturcaraan serentak.

2.1 Mutex lock
Mutex lock ialah mekanisme kunci yang paling biasa digunakan di Golang Ia boleh memastikan bahawa hanya satu goroutine boleh mengakses sumber yang dikongsi pada masa yang sama melalui kaedah Lock() dan Unlock(). Berikut ialah contoh mudah:

package main

import (
    "fmt"
    "sync"
)

var count = 0
var mutex sync.Mutex

func increment() {
    mutex.Lock()
    count++
    mutex.Unlock()
}

func main() {
    var wg sync.WaitGroup
    for i := 0; i < 1000; i++ {
        wg.Add(1)
        go func() {
            increment()
            wg.Done()
        }()
    }
    wg.Wait()
    fmt.Println("Final Count:", count)
}
Salin selepas log masuk

Dalam kod di atas, kami menggunakan sync.Mutex mutex untuk mengawal akses kepada pembolehubah kiraan. Dalam fungsi kenaikan, kami memanggil kaedah mutex.Lock() untuk memperoleh kunci sebelum mengubah suai kiraan, dan kemudian memanggil kaedah mutex.Unlock() untuk melepaskan kunci selepas pengubahsuaian selesai. Dalam urutan utama, kami memulakan 1000 goroutin untuk mengumpul kiraan dan menggunakan penyegerakan.WaitGroup untuk menunggu semua goroutin melengkapkan dan mengeluarkan nilai kiraan akhir.

2.2 Kunci baca-tulis
Kunci baca-tulis ialah mekanisme kunci khas yang digunakan untuk menyelesaikan masalah lebih banyak membaca dan kurang menulis dalam senario serentak. Kunci baca-tulis membenarkan berbilang gorout membaca sumber yang dikongsi pada masa yang sama, tetapi akan menyekat operasi baca dan tulis lain semasa operasi tulis Hanya apabila operasi tulis selesai, operasi baca dan tulis lain boleh diteruskan. Berikut ialah contoh mudah:

package main

import (
    "fmt"
    "sync"
    "time"
)

var data map[string]string
var rwLock sync.RWMutex

func readData(key string) {
    rwLock.RLock()
    defer rwLock.RUnlock()
    fmt.Println(data[key])
}

func writeData(key string, value string) {
    rwLock.Lock()
    defer rwLock.Unlock()
    data[key] = value
}

func main() {
    data = make(map[string]string)
    go func() {
        for i := 0; i < 10; i++ {
            writeData(fmt.Sprintf("key-%d", i), fmt.Sprintf("value-%d", i))
        }
    }()
    go func() {
        for i := 0; i < 10; i++ {
            readData(fmt.Sprintf("key-%d", i))
        }
    }()
    time.Sleep(time.Second)
}
Salin selepas log masuk

Dalam kod di atas, kami menggunakan penyegerakan.RWMutex baca-tulis kunci untuk melindungi operasi baca dan tulis pada pembolehubah data. Dalam fungsi readData, kami memanggil kaedah rwLock.RLock() untuk mendapatkan kunci baca dan memanggil kaedah rwLock.RUnlock() untuk melepaskan kunci baca selepas tamat, dalam fungsi writeData, kami memanggil rwLock.Lock() kaedah untuk mendapatkan kunci tulis dan tamat Kemudian panggil kaedah rwLock.Unlock() untuk melepaskan kunci tulis. Dalam urutan utama, kami memulakan dua goroutine, satu untuk menulis data kongsi dan satu untuk membaca data kongsi, dan menunggu dua goroutine menyelesaikan pelaksanaan sepanjang masa. Kaedah tidur.

Kesimpulan:
Melalui ciri goroutine dan Channel, Golang menyediakan keupayaan pengaturcaraan serentak yang mudah dan berkuasa. Melalui mekanisme kunci (kunci mutex, kunci baca-tulis, dll.), kami boleh menyelesaikan keadaan perlumbaan biasa dan masalah kebuntuan dalam pengaturcaraan serentak. Untuk pembangunan aplikasi serentak berskala besar, memahami dan menguasai ciri dan mekanisme ini akan menjadi sangat penting. Saya harap penjelasan dan contoh kod dalam artikel ini dapat membantu semua orang memahami keselamatan bersamaan dan mekanisme penguncian di Golang.

Atas ialah kandungan terperinci Penjelasan terperinci tentang ciri bahasa Golang: keselamatan serentak dan mekanisme penguncian. 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