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) }
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.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") }
在上述代码中,通过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") }
在上述代码中,通过sync.Mutex
创建了一个互斥锁mutex
。在每个Goroutine中,通过调用mutex.Lock()
和mutex.Unlock()
的配对来保护共享资源的访问。在实际的应用中,可以将需要保护的共享资源存放在结构体中,通过结构体中的互斥锁来控制对共享资源的访问。
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) } }
在上述代码中,通过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") }
在上述代码中,通过调用mutex.Lock()
和mutex.Unlock()
来保证在同一时间只能有一个Goroutine执行task()
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.
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. 🎜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!