Maison > développement back-end > Golang > le corps du texte

Impact sur les performances des mécanismes de synchronisation disponibles dans Golang

王林
Libérer: 2023-09-27 15:16:44
original
1388 Les gens l'ont consulté

Impact sur les performances des mécanismes de synchronisation disponibles dans Golang

Impact des mécanismes de synchronisation disponibles dans Golang sur les performances

Introduction :
En programmation simultanée, le mécanisme de synchronisation est crucial pour garantir que plusieurs opérations simultanées sont exécutées correctement. En tant que langage prenant en charge la programmation simultanée, Golang fournit une variété de mécanismes de synchronisation, tels que le mutex (Mutex), le verrouillage en lecture-écriture (RWLock), le sémaphore (Semaphore), la variable de condition (Cond), etc. Cependant, l'équilibre entre performances et exactitude du programme doit être soigneusement pesé lors de l'utilisation de ces mécanismes de synchronisation.

1. Mutex (Mutex)
Mutex est l'un des mécanismes de synchronisation les plus courants. Il peut protéger le code dans la section critique et n'autoriser qu'un seul thread à y accéder en même temps. Voici un exemple de code simple :

package main

import (
    "fmt"
    "sync"
)

var (
    count int
    mutex sync.Mutex
    wg    sync.WaitGroup
)

func increment() {
    defer wg.Done()
    mutex.Lock()
    defer mutex.Unlock()
    count++
}

func main() {
    for i := 0; i < 1000; i++ {
        wg.Add(1)
        go increment()
    }
    wg.Wait()
    fmt.Println("Count:", count)
}
Copier après la connexion

Dans le code ci-dessus, l'accès simultané à la variable count est protégé par un verrou mutex. Dans chaque goroutine, le verrou est obtenu en appelant la méthode Lock, et la méthode Unlock libère le verrou. Le résultat de l'exécution est correct et la valeur de count peut être garantie comme étant de 1 000. Cependant, les verrous mutex entraînent une surcharge de performances supplémentaire. Étant donné que chaque verrou implique un appel système du système d'exploitation, passant du mode utilisateur au mode noyau, il s'agit d'une opération relativement coûteuse. Lock方法获取锁,Unlock方法释放锁。运行结果是正确的,可以保证count的值为1000。然而,互斥锁会带来额外的性能开销。因为每次加锁都会涉及到操作系统的系统调用,从用户态切换到内核态,这是一个较为昂贵的操作。

二、读写锁(RWLock)
读写锁是一种特殊的同步机制,它在互斥锁的基础上提供了更灵活的访问权限控制。读写锁允许多个读操作并发进行,而对写操作进行独占。下面是一个简单的示例代码:

package main

import (
    "fmt"
    "sync"
)

var (
    count int
    rw    sync.RWMutex
    wg    sync.WaitGroup
)

func increment() {
    defer wg.Done()
    rw.Lock()
    defer rw.Unlock()
    count++
}

func readCount() int {
    rw.RLock()
    defer rw.RUnlock()
    return count
}

func main() {
    for i := 0; i < 1000; i++ {
        wg.Add(1)
        go increment()
    }
    wg.Wait()
    fmt.Println("Count:", readCount())
}
Copier après la connexion

上述代码中,我们使用读写锁来保护count变量的并发访问。通过调用RLock方法进行多个读操作,并调用Lock

2. Verrouillage en lecture-écriture (RWLock)

Le verrouillage en lecture-écriture est un mécanisme de synchronisation spécial qui fournit un contrôle d'accès plus flexible basé sur des verrous mutex. Les verrous en lecture-écriture permettent à plusieurs opérations de lecture de se dérouler simultanément, tandis que les opérations d'écriture sont exclusives. Voici un exemple de code simple :

package main

import (
    "fmt"
)

var (
    count   int
    ch      = make(chan struct{}, 1)
    results = make(chan int, 1000)
)

func increment() {
    ch <- struct{}{} // 获取信号量
    count++
    results <- count
    <-ch // 释放信号量
}

func main() {
    for i := 0; i < 1000; i++ {
        go increment()
    }
    for i := 0; i < 1000; i++ {
        <-results
    }
    fmt.Println("Count:", count)
}
Copier après la connexion
Dans le code ci-dessus, nous utilisons des verrous en lecture-écriture pour protéger l'accès simultané à la variable count. Effectuez plusieurs opérations de lecture en appelant la méthode RLock et appelez la méthode Lock pour les opérations d'écriture. Les verrous en lecture-écriture peuvent améliorer les performances de concurrence du programme, car plusieurs goroutines sont autorisées à lire des données en même temps et les opérations de lecture ne s'excluent pas mutuellement. Ce n'est que lorsqu'une goroutine doit effectuer une opération d'écriture qu'elle doit être verrouillée. Pour la plupart des scénarios de lecture et d’écriture, les verrous en lecture-écriture constituent un bon choix.

3. Sémaphore

Le sémaphore est un mécanisme de synchronisation largement utilisé en programmation concurrente. Il est généralement utilisé pour contrôler l'accès aux ressources critiques. La bibliothèque standard de Golang ne fournit pas d'implémentation native de sémaphore, mais le comportement du sémaphore peut être simulé via des canaux combinés avec des goroutines. Voici un exemple de code :
rrreee

Dans le code ci-dessus, nous implémentons le mécanisme de sémaphore via un canal tamponné. Acquérir et libérer des sémaphores en envoyant et en recevant des données sur le canal. L'utilisation de sémaphores permet de contrôler de manière flexible les ressources critiques et de limiter le nombre de goroutines qui accèdent aux ressources en même temps. 🎜🎜Résumé : 🎜En programmation concurrente, le mécanisme de synchronisation est indispensable. Le choix d'un mécanisme de synchronisation approprié peut garantir l'exactitude du programme et améliorer les performances de concurrence dans une certaine mesure. Les verrous mutex constituent le mécanisme de synchronisation le plus courant, qui peut protéger l'accès simultané aux ressources critiques, mais peut entraîner une légère surcharge de performances. Les verrous en lecture-écriture offrent un contrôle d'accès plus flexible et conviennent aux scénarios où il y a plus de lecture et moins d'écriture. Le sémaphore est un mécanisme de synchronisation général qui peut contrôler efficacement l'accès aux ressources critiques. En fonction des besoins et des scénarios spécifiques, le choix d'un mécanisme de synchronisation approprié peut optimiser les performances du programme. 🎜

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!

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