Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mari kita bincangkan tentang beberapa teknik pengaturcaraan serentak Golang yang biasa digunakan

Mari kita bincangkan tentang beberapa teknik pengaturcaraan serentak Golang yang biasa digunakan

PHPz
PHPzasal
2023-04-06 08:56:10627semak imbas

Golang ialah bahasa pengaturcaraan yang digunakan secara meluas untuk membina atur cara yang cekap, berprestasi tinggi, selari dan teragih. Ia mempunyai kelebihan sintaks yang ringkas dan ringan sambil dapat menggunakan pengaturcaraan serentak dengan mudah.

Di Golang, menggunakan goroutin dan saluran untuk melaksanakan pengaturcaraan serentak ialah cara yang popular. Goroutine ialah utas ringan yang unik untuk Golang Ia boleh melaksanakan berbilang tugasan pada masa yang sama dalam satu utas, dan boleh bertukar dengan overhed sifar apabila tugasan tidak disekat. Saluran ialah primitif penyegerakan yang membolehkan berbilang gorout bekerjasama untuk menyelesaikan pemindahan data dan penyegerakan antara tugas.

Mari kita lihat beberapa teknik pengaturcaraan serentak Golang yang biasa digunakan:

1 Gunakan goroutine untuk mencapai konkurensi

Gorutin Golang sangat mudah digunakan, sejurus sebelum fungsi. call Menambah kata kunci "pergi" mengubahnya menjadi goroutine. Contohnya:

func main() {
    //启动一个新的goroutine
    go func() {
        fmt.Println("Hello World")
    }()

    //在这里继续执行其他任务
    //...
}

Kod di atas akan mencetak "Hello World" dalam urutan lain dan fungsi utama akan terus dilaksanakan pada masa yang sama. Menggunakan goroutine boleh meningkatkan keselarasan dan kelajuan tindak balas program.

2. Gunakan saluran untuk mencapai penyegerakan data

Saluran Golang ialah primitif penyegerakan yang digunakan untuk memindahkan data dan menyegerak antara berbilang gorouti. Saluran boleh mewujudkan komunikasi antara mana-mana dua goroutine Ia mempunyai dua cara untuk menghantar dan menerima mesej, menyekat dan tidak menyekat.

Berikut ialah contoh mudah menggunakan saluran untuk memindahkan data:

func main() {
    //创建一个整数类型的channel
    ch := make(chan int)

    //启动一个goroutine发送数据
    go func() {
        ch <- 123  //发送数据到channel中
    }()

    //接收刚刚发送的数据
    num := <- ch  //从channel中接收数据
    fmt.Println(num)  //输出:123
}

Dalam kod di atas, kami mula-mula mencipta saluran jenis integer. Kemudian goroutine dimulakan untuk menghantar data kepadanya, dan kemudian data diterima dari saluran dalam benang utama dan output. Saluran boleh digunakan untuk memindahkan dan menyegerakkan data antara gorouti yang berbeza.

3. Gunakan pakej penyegerakan untuk mencapai penyegerakan

penyegerakan ialah koleksi primitif penyegerakan di Golang, termasuk Mutex, RWMutex, Cond, Once, WaitGroup, dsb. Boleh digunakan untuk mencapai tahap penyegerakan dan kawalan keselamatan benang yang lebih tinggi.

Mutex ialah kunci mutex yang digunakan untuk melindungi sumber kongsi. Gunakan fungsi Lock() untuk mendapatkan mutex sebelum mengakses bahagian kritikal, dan gunakan fungsi Unlock() untuk melepaskan kunci selepas akses selesai.

Berikut ialah contoh kaunter selamat benang yang dilaksanakan menggunakan Mutex:

import (
    "fmt"
    "sync"
)

type Counter struct {
    count int
    mu    sync.Mutex
}

func (c *Counter) Increment() {
    //获取互斥锁并增加计数
    c.mu.Lock()
    c.count++
    c.mu.Unlock()
}

func (c *Counter) Count() int {
    //获取互斥锁并返回计数
    c.mu.Lock()
    defer c.mu.Unlock()
    return c.count
}

func main() {
    //创建一个计数器
    c := Counter{}

    //启动多个goroutine增加计数
    for i := 0; i < 1000; i++ {
        go c.Increment()
    }

    //等待所有goroutine执行完成
    time.Sleep(time.Second)

    //输出计数器的值
    fmt.Println(c.Count())
}

Dalam kod di atas, kami menggunakan Mutex untuk melindungi sumber kongsi kaunter dan memastikan ia dilaksanakan serentak dengan keselamatan benang goroutine berbilang.

4. Gunakan pakej konteks untuk melaksanakan kawalan tamat masa

Dalam Golang, konteks ialah konteks transitif yang digunakan untuk mengawal kelakuan subpokok goroutine (serupa dengan ThreadLocal di Java).

Pakej konteks menyediakan beberapa fungsi, seperti WithCancel(), WithDeadline(), WithTimeout(), dsb., yang boleh digunakan untuk memulakan pengurusan konteks goroutine. Fungsi ini mengembalikan objek konteks baharu dan fungsi yang boleh dipanggil untuk menandakan konteks sebagai dibatalkan apabila konteks perlu dibatalkan. Dalam goroutine, anda boleh menggunakan saluran Done() Context untuk mendapatkan isyarat pembatalan.

Berikut ialah contoh kawalan tamat masa yang dilaksanakan menggunakan konteks:

import (
    "fmt"
    "context"
)

func main() {
    //创建一个带超时的上下文
    ctx, cancel := context.WithTimeout(context.Background(), time.Second)

    //执行一个耗时任务
    go func() {
        time.Sleep(time.Second * 2)
        fmt.Println("Goroutine Done")
    }()

    //等待上下文取消信号
    select {
    case <-ctx.Done():
        fmt.Println("Timeout")
    }

    //取消上下文
    cancel()
}

Dalam kod di atas, kami mula-mula mencipta konteks dengan tamat masa 1 saat dan memulakan 2 saat yang memakan masa daripada goroutine, kemudian tunggu saluran Done() konteks dalam fungsi utama, dan keluarkan "Timeout" sebaik sahaja isyarat pembatalan diterima.

5. Gunakan penyegerakan/atom untuk melaksanakan operasi atom semasa pertandingan

Di Golang, pakej penyegerakan/atom menyediakan beberapa fungsi operasi atom yang boleh digunakan untuk mengemas kini integer dikongsi semasa pertandingan nilai. Menggunakan operasi atom boleh mengelakkan keadaan perlumbaan apabila berbilang goroutin dilaksanakan serentak.

Berikut ialah contoh operasi atom menggunakan pakej penyegerakan/atom untuk mengeluarkan pembilang heksadesimal:

import (
    "fmt"
    "sync/atomic"
)

func main() {
    //定义一个uint32的计数器
    var counter uint32

    //启动多个goroutine更新计数器
    for i := 0; i < 1000; i++ {
        go func() {
            //原子地增加计数器
            atomic.AddUint32(&counter, 1)
        }()
    }

    //等待所有goroutine执行完成
    time.Sleep(time.Second)

    //输出计数器的值
    fmt.Printf("0x%x\n", atomic.LoadUint32(&counter))
}

Dalam kod di atas, kami mentakrifkan pembilang jenis uint32, Dan gunakan fungsi AddUint32() untuk menambah kiraan secara atom apabila berbilang goroutin dilaksanakan serentak. Akhirnya, nilai perenambelasan pembilang adalah output.

Ringkasan:

Pengaturcaraan serentak di Golang mempunyai ciri-ciri kesederhanaan, ringan dan prestasi tinggi Melalui penggunaan fungsi alat seperti goroutine, saluran dan penyegerakan, kerjasama antara utas boleh dilakukan mudah direalisasikan dan komunikasi untuk meningkatkan prestasi serentak dan kelajuan tindak balas program. Pada masa yang sama, perhatian perlu diberikan kepada penggunaan mekanisme penyegerakan untuk mengelakkan isu keselamatan benang.

Atas ialah kandungan terperinci Mari kita bincangkan tentang beberapa teknik pengaturcaraan serentak Golang yang biasa digunakan. 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
Artikel sebelumnya:Apakah kebaikan golang?Artikel seterusnya:Apakah kebaikan golang?