Penjelasan terperinci tentang mekanisme penyegerakan dan pengecualian bersama Goroutines dalam pengaturcaraan serentak Golang

PHPz
Lepaskan: 2023-07-20 11:25:10
asal
959 orang telah melayarinya

Penjelasan terperinci tentang mekanisme penyegerakan dan pengecualian bersama Goroutines dalam pengaturcaraan serentak Golang

Dengan populariti pemproses berbilang teras dan peningkatan berterusan prestasi komputer, cara menggunakan sepenuhnya berbilang teras pemproses untuk pengkomputeran selari telah menjadi satu perkara penting. isu yang dihadapi oleh pemaju. Pengaturcaraan serentak adalah salah satu teknologi utama untuk menyelesaikan masalah ini. Di Golang, Goroutine dan Saluran digunakan secara meluas untuk melaksanakan pengaturcaraan serentak. Antaranya, Goroutines ialah utas ringan yang boleh mencapai pemprosesan tugas berkonkurensi tinggi. Untuk memastikan kerjasama yang betul antara berbilang Goroutine, mekanisme penyegerakan dan pengecualian bersama memainkan peranan yang penting.

1. Konsep asas Goroutines
Di Golang, Goroutines ialah benang ringan yang boleh dilaksanakan serentak dengan Goroutines lain. Goroutines memerlukan lebih sedikit sumber untuk mencipta dan memusnahkan daripada benang tradisional dan boleh menggunakan sumber sistem dengan lebih cekap.

Goroutines dicipta menggunakan kata kunci "go". Kod sampel adalah seperti berikut:

package main

import (
    "fmt"
    "time"
)

func task1() {
    for i := 0; i < 5; i++ {
        fmt.Println("Task 1:", i)
        time.Sleep(time.Millisecond * 500)
    }
}

func task2() {
    for i := 0; i < 5; i++ {
        fmt.Println("Task 2:", i)
        time.Sleep(time.Millisecond * 500)
    }
}

func main() {
    go task1()
    go task2()

    time.Sleep(time.Millisecond * 3000)
}
Salin selepas log masuk

Dalam kod di atas, dua Goroutine dicipta melalui kata kunci "go" dan laksanakan fungsi task1() dan task2() masing-masing. Dalam fungsi main(), tunggu selama 3 saat melalui fungsi time.Sleep() untuk memastikan bahawa Goroutines mempunyai masa yang mencukupi untuk menyelesaikan pelaksanaan. task1()task2()函数。在main()函数中,通过time.Sleep()函数等待3秒钟,保证Goroutines有足够的时间执行完毕。

二、Goroutines的同步与互斥机制
在实际的并发编程中,多个Goroutines可能需要共享某些资源。这时候就需要通过同步与互斥机制来确保资源的正确访问。

  1. 同步
    在Golang中,常用的同步机制有WaitGroup、Mutex和RWMutex。

1.1 WaitGroup
WaitGroup用于等待一组Goroutines的执行完成。它的功能类似于Java中的CountDownLatch。示例代码如下:

package main

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

func task(i int, wg *sync.WaitGroup) {
    defer wg.Done()

    fmt.Println("Task", i)
    time.Sleep(time.Millisecond * 500)
}

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 5; i++ {
        wg.Add(1)
        go task(i, &wg)
    }

    wg.Wait()
    fmt.Println("All tasks finished")
}
Salin selepas log masuk

在上述代码中,通过sync.WaitGroup创建了一个等待组wg。在每个Goroutine的执行前调用wg.Add(1)将等待组计数器加1,表示有一个任务需要等待。在每个Goroutine执行完毕后调用wg.Done()将等待组计数器减1,表示一个任务已完成。最后,通过wg.Wait()等待所有任务执行完成。

1.2 Mutex
Mutex是一种互斥锁,用于保护共享资源在同一时间只能被一个Goroutine访问。示例代码如下:

package main

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

var count int
var mutex sync.Mutex

func task(i int, wg *sync.WaitGroup) {
    defer wg.Done()

    mutex.Lock()
    defer mutex.Unlock()

    count++
    fmt.Println("Task", i, "count:", count)
    time.Sleep(time.Millisecond * 500)

    mutex.Lock()
    defer mutex.Unlock()

    count--
}

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 5; i++ {
        wg.Add(1)
        go task(i, &wg)
    }

    wg.Wait()
    fmt.Println("All tasks finished")
}
Salin selepas log masuk

在上述代码中,通过sync.Mutex创建了一个互斥锁mutex。在每个Goroutine中,通过调用mutex.Lock()mutex.Unlock()的配对来保护共享资源的访问。在实际的应用中,可以将需要保护的共享资源存放在结构体中,通过结构体中的互斥锁来控制对共享资源的访问。

  1. 互斥
    除了同步外,有时候还需要通过互斥来保证某段代码在同一时间只能被一个Goroutine执行。在Golang中,常用的互斥机制有Once和Mutex。

2.1 Once
Once用于保证某段代码在程序运行期间只会执行一次。示例代码如下:

package main

import (
    "fmt"
    "sync"
)

var once sync.Once

func task() {
    fmt.Println("Task executed")
}

func main() {
    for i := 0; i < 5; i++ {
        once.Do(task)
    }
}
Salin selepas log masuk

在上述代码中,通过sync.Once创建了一个Once对象once。在每个Goroutine中,通过调用once.Do(task)来保证task()函数在整个程序运行期间只会执行一次。

2.2 Mutex
Mutex也可以用来实现互斥。示例代码如下:

package main

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

var count int
var mutex sync.Mutex

func task(i int, wg *sync.WaitGroup) {
    defer wg.Done()

    mutex.Lock()
    defer mutex.Unlock()

    fmt.Println("Task", i)
    time.Sleep(time.Millisecond * 500)
}

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 5; i++ {
        wg.Add(1)
        go task(i, &wg)
    }

    wg.Wait()
    fmt.Println("All tasks finished")
}
Salin selepas log masuk

在上述代码中,通过调用mutex.Lock()mutex.Unlock()来保证在同一时间只能有一个Goroutine执行task()

2. Penyegerakan dan mekanisme pengecualian bersama Goroutines

Dalam pengaturcaraan serentak sebenar, beberapa Goroutine mungkin perlu berkongsi sumber tertentu. Pada masa ini, mekanisme penyegerakan dan pengecualian bersama diperlukan untuk memastikan akses yang betul kepada sumber.

  1. PenyegerakanDi Golang, mekanisme penyegerakan yang biasa digunakan termasuk WaitGroup, Mutex dan RWMutex.
🎜1.1 WaitGroup🎜WaitGroup digunakan untuk menunggu pelaksanaan kumpulan Goroutines selesai. Fungsinya serupa dengan CountDownLatch di Java. Kod sampel adalah seperti berikut: 🎜rrreee🎜Dalam kod di atas, kumpulan menunggu wg dibuat melalui sync.WaitGroup. Panggil wg.Add(1) sebelum setiap Goroutine dilaksanakan untuk menambah kaunter kumpulan menunggu sebanyak 1, menunjukkan bahawa terdapat tugasan yang perlu menunggu. Selepas setiap Goroutine dilaksanakan, panggil wg.Done() untuk mengurangkan kaunter kumpulan menunggu sebanyak 1, menunjukkan bahawa tugas telah selesai. Akhir sekali, tunggu semua tugasan diselesaikan melalui wg.Wait(). 🎜🎜1.2 Mutex🎜Mutex ialah kunci mutex, digunakan untuk melindungi sumber kongsi yang hanya boleh diakses oleh satu Goroutine pada masa yang sama. Kod sampel adalah seperti berikut: 🎜rrreee🎜Dalam kod di atas, kunci mutex mutex dicipta melalui sync.Mutex. Dalam setiap Goroutine, akses kepada sumber yang dikongsi dilindungi dengan memanggil sepasang mutex.Lock() dan mutex.Unlock(). Dalam aplikasi sebenar, sumber kongsi yang perlu dilindungi boleh disimpan dalam struktur, dan akses kepada sumber kongsi boleh dikawal melalui kunci mutex dalam struktur. 🎜
  1. Pengecualian bersama🎜Selain penyegerakan, kadangkala pengecualian bersama juga diperlukan untuk memastikan sekeping kod tertentu hanya boleh dilaksanakan oleh satu Goroutine pada masa yang sama. Di Golang, mekanisme pengecualian bersama yang biasa digunakan termasuk Once dan Mutex.
🎜2.1 Sekali🎜Sekali digunakan untuk memastikan sekeping kod tertentu hanya akan dilaksanakan sekali semasa program dijalankan. Kod sampel adalah seperti berikut: 🎜rrreee🎜Dalam kod di atas, objek Once sekali dicipta melalui sync.Once. Dalam setiap Goroutine, memanggil sekali.Do(task) memastikan bahawa fungsi task() hanya akan dilaksanakan sekali sepanjang masa berjalan program. 🎜🎜2.2 Mutex🎜Mutex juga boleh digunakan untuk melaksanakan pengecualian bersama. Kod sampel adalah seperti berikut: 🎜rrreee🎜Dalam kod di atas, dengan memanggil mutex.Lock() dan mutex.Unlock() untuk memastikan bahawa hanya satu Goroutine boleh dilaksanakan pada masa yang sama fungsi task() dan mengakses sumber yang dikongsi. 🎜🎜Ringkasan🎜Melalui pengenalan artikel ini, kami telah mengetahui tentang penyegerakan dan mekanisme pengecualian bersama Goroutines dalam pengaturcaraan serentak Golang. Dalam aplikasi sebenar, mekanisme penyegerakan dan pengecualian bersama adalah kunci untuk memastikan kerjasama yang betul antara berbilang Goroutine. Penggunaan penyegerakan yang betul dan mekanisme pengecualian bersama seperti WaitGroup, Mutex dan RWMutex boleh memastikan akses yang betul kepada sumber yang dikongsi, dengan itu mencapai pengaturcaraan serentak yang cekap. 🎜

Atas ialah kandungan terperinci Penjelasan terperinci tentang mekanisme penyegerakan dan pengecualian bersama Goroutines dalam pengaturcaraan serentak 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
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!