Maison >développement back-end >Golang >Explication détaillée du mécanisme de synchronisation et d'exclusion mutuelle des Goroutines dans la programmation simultanée Golang
Explication détaillée du mécanisme de synchronisation et d'exclusion mutuelle des Goroutines dans la programmation simultanée Golang
Avec la popularité des processeurs multicœurs et l'amélioration continue des performances des ordinateurs, comment utiliser pleinement plusieurs cœurs de processeur pour le calcul parallèle est devenu une question importante problème rencontré par les développeurs. La programmation simultanée est l'une des technologies clés pour résoudre ce problème. Dans Golang, les Goroutines et les canaux sont largement utilisés pour implémenter la programmation simultanée. Parmi eux, les Goroutines sont des threads légers capables de réaliser un traitement de tâches à haute concurrence. Afin d'assurer la bonne coopération entre plusieurs Goroutines, les mécanismes de synchronisation et d'exclusion mutuelle jouent un rôle crucial.
1. Le concept de base des Goroutines
Dans Golang, les Goroutines sont des threads légers qui peuvent s'exécuter simultanément avec d'autres Goroutines. Les goroutines coûtent moins de ressources à créer et à détruire que les threads traditionnels et peuvent utiliser les ressources système plus efficacement.
Les Goroutines sont créées avec le mot-clé "go". L'exemple de code est le suivant :
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) }
Dans le code ci-dessus, deux Goroutines sont créées via le mot-clé "go" et exécutent les fonctions task1()
et task2()
respectivement. Dans la fonction main()
, attendez 3 secondes via la fonction time.Sleep()
pour vous assurer que les Goroutines ont suffisamment de temps pour terminer l'exécution. 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()
Dans la programmation simultanée réelle, plusieurs Goroutines peuvent avoir besoin de partager certaines ressources. À l’heure actuelle, des mécanismes de synchronisation et d’exclusion mutuelle sont nécessaires pour garantir un accès correct aux ressources.
wg
est créé via sync.WaitGroup
. Appelez wg.Add(1)
avant que chaque Goroutine ne soit exécutée pour incrémenter le compteur de groupe en attente de 1, indiquant qu'il y a une tâche qui doit attendre. Après l'exécution de chaque Goroutine, appelez wg.Done()
pour décrémenter le compteur des groupes en attente de 1, indiquant qu'une tâche est terminée. Enfin, attendez que toutes les tâches soient terminées via wg.Wait()
. 🎜🎜1.2 Mutex🎜Mutex est un verrou mutex, utilisé pour protéger les ressources partagées qui ne peuvent être accessibles que par un seul Goroutine à la fois. L'exemple de code est le suivant : 🎜rrreee🎜Dans le code ci-dessus, un verrou mutex mutex
est créé via sync.Mutex
. Dans chaque Goroutine, l'accès aux ressources partagées est protégé en appelant une paire de mutex.Lock()
et mutex.Unlock()
. Dans les applications réelles, les ressources partagées qui doivent être protégées peuvent être stockées dans la structure et l'accès aux ressources partagées peut être contrôlé via le verrou mutex dans la structure. 🎜once
est créé via sync.Once
. Dans chaque Goroutine, l'appel de once.Do(task)
garantit que la fonction task()
ne sera exécutée qu'une seule fois pendant toute la durée d'exécution du programme. 🎜🎜2.2 Mutex🎜Mutex peut également être utilisé pour mettre en œuvre une exclusion mutuelle. L'exemple de code est le suivant : 🎜rrreee🎜Dans le code ci-dessus, en appelant mutex.Lock()
et mutex.Unlock()
pour vous assurer qu'un seul Goroutine peut être exécuté en même temps la fonction task()
et accède aux ressources partagées. 🎜🎜Résumé🎜Grâce à l'introduction de cet article, nous avons découvert le mécanisme de synchronisation et d'exclusion mutuelle des Goroutines dans la programmation simultanée Golang. Dans les applications réelles, les mécanismes de synchronisation et d'exclusion mutuelle sont la clé pour garantir une collaboration correcte entre plusieurs Goroutines. Une utilisation appropriée des mécanismes de synchronisation et d'exclusion mutuelle tels que WaitGroup, Mutex et RWMutex peut garantir un accès correct aux ressources partagées, permettant ainsi une programmation simultanée efficace. 🎜Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!