Maison  >  Article  >  développement back-end  >  Utiliser le mécanisme de verrouillage de Golang pour obtenir un traitement simultané hautes performances

Utiliser le mécanisme de verrouillage de Golang pour obtenir un traitement simultané hautes performances

WBOY
WBOYoriginal
2023-09-28 09:53:141263parcourir

Utiliser le mécanisme de verrouillage de Golang pour obtenir un traitement simultané hautes performances

Utilisez le mécanisme de verrouillage de Golang pour obtenir un traitement simultané hautes performances

Dans la programmation simultanée, il est très important de garantir la cohérence des données et d'éviter les conditions de concurrence. Golang fournit un riche mécanisme de traitement simultané, parmi lequel le mécanisme de verrouillage est un moyen courant de synchroniser l'accès aux ressources partagées. Cet article explique comment utiliser le mécanisme de verrouillage de Golang pour obtenir un traitement simultané hautes performances et fournit des exemples de code spécifiques.

1. Le mécanisme de verrouillage de Golang
Golang propose deux mécanismes de verrouillage courants : le verrouillage d'exclusion mutuelle (Mutex) et le verrouillage en lecture-écriture (RWMutex).

  1. Mutex (Mutex)
    Mutex est un mécanisme de verrouillage de base fourni par Golang. Cela garantit qu'un seul Goroutine peut accéder aux ressources partagées à la fois, et que les autres Goroutines doivent attendre que le verrou soit libéré. Les verrous mutex ont deux méthodes couramment utilisées : Lock() et Unlock().

L'exemple de code est le suivant :

package main

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

var count int
var mutex sync.Mutex

func main() {
    wg := sync.WaitGroup{}
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go increment(&wg)
    }
    wg.Wait()
    fmt.Println("Final count:", count)
}

func increment(wg *sync.WaitGroup) {
    mutex.Lock() // 获取互斥锁
    defer mutex.Unlock() // 在函数退出时释放锁
    defer wg.Done() // 减少 WaitGroup 的计数
    time.Sleep(time.Second) // 模拟耗时操作
    count++
}

Dans le code ci-dessus, nous créons une variable globale count, puis utilisons le mutex de verrouillage d'exclusion mutuelle pour garantir que l'opération de count est thread-safe. Dans la fonction d'incrémentation, nous appelons d'abord mutex.Lock() pour acquérir le verrou, et différons mutex.Unlock() pour libérer le verrou à la fin de la fonction. Cela garantit qu'un seul Goroutine peut accéder au nombre à la fois, et que les autres Goroutines doivent attendre que le verrou soit libéré.

  1. Verrouillage en lecture-écriture (RWMutex)
    Le verrouillage en lecture-écriture est un mécanisme de verrouillage avancé fourni par Golang. Il peut prendre en charge plusieurs opérations de lecture Goroutines sur des ressources partagées en même temps, mais un accès exclusif est requis pour les opérations d'écriture. Il existe trois méthodes couramment utilisées pour les verrous en lecture-écriture : RLock(), RUnlock() et Lock().

L'exemple de code est le suivant :

package main

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

var count int
var rwMutex sync.RWMutex

func main() {
    wg := sync.WaitGroup{}
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go read(&wg)
    }
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go write(&wg)
    }
    wg.Wait()
    fmt.Println("Final count:", count)
}

func read(wg *sync.WaitGroup) {
    rwMutex.RLock() // 获取读锁
    defer rwMutex.RUnlock() // 在函数退出时释放读锁
    defer wg.Done() // 减少 WaitGroup 的计数
    time.Sleep(time.Second) // 模拟耗时操作
    fmt.Println("Read count:", count)
}

func write(wg *sync.WaitGroup) {
    rwMutex.Lock() // 获取写锁
    defer rwMutex.Unlock() // 在函数退出时释放写锁
    defer wg.Done() // 减少 WaitGroup 的计数
    time.Sleep(time.Second) // 模拟耗时操作
    count++
    fmt.Println("Write count:", count)
}

Dans le code ci-dessus, nous utilisons le verrou en lecture-écriture rwMutex pour garantir la sécurité des accès simultanés au comptage. Dans la fonction de lecture, nous appelons rwMutex.RLock() pour acquérir le verrou de lecture, et différons rwMutex.RUnlock() pour libérer le verrou de lecture lorsque la fonction se termine dans la fonction d'écriture, nous appelons rwMutex.Lock() pour acquérir le verrou de lecture ; verrou d'écriture, libérez le verrou d'écriture en différant rwMutex.Unlock() lorsque la fonction se termine. Cela permet de compter les accès simultanés en lecture et en écriture.

2. Traitement simultané hautes performances
L'utilisation d'un mécanisme de verrouillage peut garantir la cohérence des données et éviter les conditions de concurrence, mais une utilisation excessive des verrous peut réduire les performances de concurrence. Afin d'obtenir un traitement simultané haute performance, nous pouvons adopter les stratégies suivantes :

  1. Réduire la granularité du verrou
    Si la granularité du verrou est trop grande, c'est-à-dire que trop de code est verrouillé, cela entraînera une diminution des performances de concurrence. Par conséquent, nous devrions essayer de réduire autant que possible la granularité du verrou, verrouiller uniquement les blocs de code nécessaires et essayer d'éviter d'effectuer des opérations fastidieuses dans le verrou.
  2. Utilisez des verrous en lecture-écriture
    Les verrous en lecture-écriture peuvent prendre en charge plusieurs opérations de lecture Goroutines sur des ressources partagées en même temps, ce qui peut améliorer considérablement les performances de concurrence. Pour la plupart des scénarios, il y a beaucoup plus d'opérations de lecture que d'opérations d'écriture, donc l'utilisation de verrous en lecture-écriture peut utiliser pleinement les ressources système.
  3. Utilisez des structures de données sans verrouillage
    Golang fournit certaines structures de données sans verrouillage, telles que les fonctions d'opération atomique dans le package atomique. L’utilisation de structures de données sans verrouillage peut éliminer la surcharge causée par les verrous et améliorer encore les performances de concurrence. Cependant, il convient de noter que la mise en œuvre de structures de données sans verrouillage est plus complexe et que la sécurité de la concurrence doit être soigneusement étudiée.

Résumé
En programmation simultanée, le mécanisme de verrouillage est un moyen courant de synchroniser l'accès aux ressources partagées. Golang fournit deux mécanismes de verrouillage courants : les verrous mutex et les verrous en lecture-écriture. En utilisant rationnellement le mécanisme de verrouillage, vous pouvez garantir la cohérence des données, éviter les conditions de concurrence et améliorer les performances de concurrence.

En réduisant la granularité des verrous, en utilisant des verrous en lecture-écriture et en utilisant des structures de données sans verrou, nous pouvons encore améliorer les performances de concurrence. Cependant, dans les applications réelles, il est nécessaire de réfléchir de manière approfondie à la sélection de mécanismes de verrouillage appropriés et de stratégies d'optimisation des performances en fonction de circonstances spécifiques.

Références :

  1. Documentation officielle de Golang : https://golang.org/doc/
  2. Modèles de concurrence Go : https://talks.golang.org/2012/concurrency.slide#1

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!

Déclaration:
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