Rumah > pembangunan bahagian belakang > Golang > Perkongsian praktikal penyegerakan dan perlindungan kunci fungsi Golang

Perkongsian praktikal penyegerakan dan perlindungan kunci fungsi Golang

WBOY
Lepaskan: 2023-05-16 09:04:57
asal
1652 orang telah melayarinya

Dengan pembangunan Internet dan popularisasi pengkomputeran awan dan teknologi data besar, sistem perisian moden perlu memproses lebih banyak data, di samping memastikan kecekapan dan kebolehpercayaan sistem. Dalam konteks ini, prestasi dan ciri teknikal bahasa menjadi sangat penting. Antaranya, Golang, sebagai bahasa pengaturcaraan yang cekap, ringan dan sangat sesuai, telah mendapat lebih banyak perhatian dan aplikasi dalam beberapa tahun kebelakangan ini. Artikel ini akan membincangkan amalan penyegerakan dan perlindungan kunci fungsi Golang, dan menyediakan beberapa perkongsian pengalaman berguna untuk pembangun Golang.

  1. Prinsip dan kaedah penyegerakan

Penyegerakan ialah kunci kerjasama antara berbilang rangkaian atau proses Tujuan utamanya adalah untuk memastikan akses dan perlindungan yang betul bagi pelbagai sumber. . Di Golang, cara utama untuk merealisasikan penyegerakan adalah seperti berikut:

1.1 Kunci Mutex (sync.Mutex)

Kunci Mutex ialah mekanisme penyegerakan paling asas di Golang. Peranan utamanya adalah untuk memastikan bahawa hanya satu goroutine boleh mengakses sumber yang dikongsi pada masa yang sama. Apabila goroutine meminta sumber, ia akan cuba memperoleh kunci Jika ia tidak dapat memperolehnya, ia akan disekat sehingga kunci dilepaskan. Berikut ialah contoh pelaksanaan mutex mudah:

package main

import (
    "fmt"
    "sync"
)

var count int
var mu sync.Mutex // 互斥锁

func main() {
    for i := 0; i < 10; i++ {
        go increase()
    }

    // 等待所有goroutine执行完成
    for {
        mu.Lock()
        if count == 10 {
            mu.Unlock()
            break
        }
        mu.Unlock()
    }

    fmt.Println("count:", count)
}

func increase() {
    mu.Lock()
    defer mu.Unlock()
    count += 1
}
Salin selepas log masuk
Salin selepas log masuk

Dalam contoh di atas, kami menggunakan mutex untuk memastikan operasi atom bagi kiraan pembolehubah yang dikongsi. Di dalam fungsi peningkatan, kita mula-mula memperoleh kunci mutex, kemudian melakukan operasi kenaikan pada kiraan, dan akhirnya melepaskan kunci. Dengan cara ini, kami boleh menghalang akses serentak untuk mengira daripada menyebabkan hasil yang tidak dijangka.

1.2 Kunci baca-tulis (sync.RWMutex)

RWMutex ialah kunci mutex lanjutan yang menyokong berbilang operasi baca serentak, tetapi hanya membenarkan satu operasi tulis. Dalam pelaksanaan, ia mengatur operasi baca berbilang goroutin dengan menukar antara mod baca dan tulis, dengan itu meningkatkan prestasi serentak. Berikut ialah contoh pelaksanaan kunci baca-tulis yang mudah:

package main

import (
    "fmt"
    "sync"
)

var count int
var mu sync.RWMutex // 读写锁

func main() {
    for i := 0; i < 10; i++ {
        go increase()
    }

    // 等待所有goroutine执行完成
    for {
        mu.RLock()
        if count == 10 {
            mu.RUnlock()
            break
        }
        mu.RUnlock()
    }

    fmt.Println("count:", count)
}

func increase() {
    mu.Lock()
    defer mu.Unlock()
    count += 1
}
Salin selepas log masuk

Dalam contoh di atas, kami menggunakan kunci baca-tulis untuk memastikan operasi atom bagi kiraan pembolehubah yang dikongsi. Di dalam fungsi peningkatan, kita mula-mula memperoleh kunci tulis bagi kunci baca-tulis, kemudian lakukan operasi kenaikan pada kiraan, dan akhirnya lepaskan kunci. Dengan cara ini, kami boleh menghalang akses serentak untuk mengira daripada menyebabkan hasil yang tidak dijangka.

  1. Amalan perlindungan kunci

Selain mekanisme penyegerakan, Golang turut menyediakan beberapa kaedah praktikal perlindungan kunci untuk memastikan integriti dan keselamatan data. Berikut ialah pengenalan terperinci kepada beberapa kaedah praktikal:

2.1 Operasi atom (segerak/atom)

Kendalian atom ialah teknologi yang boleh memastikan penyegerakan data tanpa mengunci. Golang menyediakan satu siri fungsi operasi atom untuk melaksanakan fungsi penyegerakan memori asas. Berikut ialah contoh:

package main

import (
    "fmt"
    "sync/atomic"
)

var count int32

func main() {
    for i := 0; i < 10; i++ {
        go increase()
    }

    // 等待所有goroutine执行完成
    for {
        if atomic.LoadInt32(&count) == 10 {
            break
        }
    }

    fmt.Println("count:", count)
}

func increase() {
    atomic.AddInt32(&count, 1)
}
Salin selepas log masuk

Dalam contoh di atas, kami menggunakan fungsi operasi atom atomic.AddInt32() untuk memastikan operasi penambahan kiraan adalah atom, dengan itu mengelakkan rasuah data yang disebabkan oleh keadaan bangsa yang tidak normal.

2.2 Komunikasi Saluran

Saluran ialah alat penyegerakan yang penting di Golang Ia memastikan ketepatan data melalui komunikasi antara goroutine. Saluran agak serupa dengan paip Unix, yang membenarkan satu goroutine menghantar blok data ke goroutine lain, atau menerima blok data. Berikut ialah contoh:

package main

import (
    "fmt"
)

func main() {
    ch := make(chan int)
    go increase(ch)

    // 接收所有增加的值
    count := 0
    for i := 0; i < 10; i++ {
       count += <-ch
    }

    fmt.Println("count:", count)
}

func increase(ch chan int) {
    for i := 0; i < 10; i++ {
       ch <- 1
    }
    close(ch)
}
Salin selepas log masuk

Dalam contoh di atas, kami menggunakan saluran untuk menghalang keadaan perlumbaan yang disebabkan oleh kiraan data dikongsi diakses serentak oleh berbilang goroutin. Di dalam fungsi peningkatan, kami menghantar 10 1s ke fungsi utama melalui saluran untuk melakukan operasi mengira. Di dalam fungsi utama, kami menerima data dalam saluran melalui gelung dan mengumpulkannya ke dalam pembolehubah kiraan, dengan itu mengelakkan pengecualian data yang disebabkan oleh keadaan perlumbaan.

2.3 Pernyataan penangguhan penyegerakan.Mutex

Di Golang, kunci mutex selalunya menggunakan pernyataan penangguhan untuk memastikan pelepasan kunci yang betul. Pernyataan tangguh ialah mekanisme yang menyebabkan penyataan dilaksanakan apabila fungsi kembali. Ia boleh mengelakkan pengecualian program yang disebabkan oleh terlupa untuk melepaskan kunci. Berikut ialah contoh:

package main

import (
    "fmt"
    "sync"
)

var count int
var mu sync.Mutex // 互斥锁

func main() {
    for i := 0; i < 10; i++ {
        go increase()
    }

    // 等待所有goroutine执行完成
    for {
        mu.Lock()
        if count == 10 {
            mu.Unlock()
            break
        }
        mu.Unlock()
    }

    fmt.Println("count:", count)
}

func increase() {
    mu.Lock()
    defer mu.Unlock()
    count += 1
}
Salin selepas log masuk
Salin selepas log masuk

Dalam contoh di atas, kami menggunakan pernyataan tangguh untuk memastikan pelepasan kunci mutex yang betul. Apabila goroutine meninggalkan fungsi peningkatan, penyata tangguh akan melepaskan kunci secara automatik untuk memastikan bahawa pada kali seterusnya kunci diperoleh, ia boleh dilaksanakan dengan jayanya.

Kesimpulan

Di atas adalah perkongsian praktikal penyegerakan dan perlindungan kunci fungsi Golang. Melalui aplikasi kunci mutex, kunci baca-tulis, operasi atom, komunikasi Saluran dan pernyataan tangguh, kami dapat memastikan ketepatan dan keselamatan data dengan lebih baik dalam pengaturcaraan berbilang benang Golang. Sama ada dalam sistem pengkomputeran awan berskala besar, sistem teragih atau sistem pemprosesan data masa nyata, penyegerakan dan teknologi perlindungan kunci ini sangat penting.

Atas ialah kandungan terperinci Perkongsian praktikal penyegerakan dan perlindungan kunci fungsi Golang. 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