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

PHPz
Libérer: 2023-07-20 11:25:10
original
988 Les gens l'ont consulté

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)
}
Copier après la connexion

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. 同步
    在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")
}
Copier après la connexion

在上述代码中,通过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")
}
Copier après la connexion

在上述代码中,通过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)
    }
}
Copier après la connexion

在上述代码中,通过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")
}
Copier après la connexion

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

2. Mécanisme de synchronisation et d'exclusion mutuelle des Goroutines

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.

  1. SynchronisationDans Golang, les mécanismes de synchronisation couramment utilisés incluent WaitGroup, Mutex et RWMutex.
🎜1.1 WaitGroup🎜WaitGroup est utilisé pour attendre la fin de l'exécution d'un groupe de Goroutines. Sa fonctionnalité est similaire à CountDownLatch en Java. L'exemple de code est le suivant : 🎜rrreee🎜Dans le code ci-dessus, un groupe d'attente 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. 🎜
  1. Exclusion mutuelle🎜En plus de la synchronisation, une exclusion mutuelle est parfois également nécessaire pour garantir qu'un certain morceau de code ne peut être exécuté que par un seul Goroutine à la fois. Dans Golang, les mécanismes d'exclusion mutuelle couramment utilisés incluent Once et Mutex.
🎜2.1 Once🎜Once est utilisé pour garantir qu'un certain morceau de code ne sera exécuté qu'une seule fois pendant l'exécution du programme. L'exemple de code est le suivant : 🎜rrreee🎜Dans le code ci-dessus, un objet Once 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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal