Maison  >  Article  >  développement back-end  >  Utiliser la technologie de synchronisation de Golang pour obtenir une simultanéité haute performance

Utiliser la technologie de synchronisation de Golang pour obtenir une simultanéité haute performance

WBOY
WBOYoriginal
2023-09-28 16:42:291070parcourir

Utiliser la technologie de synchronisation de Golang pour obtenir une simultanéité haute performance

Utilisez la technologie de synchronisation de Golang pour obtenir une simultanéité haute performance

Résumé :
Golang est un langage de programmation très puissant en termes de traitement simultané. Il permet une écriture haute performance grâce à des primitives de synchronisation intégrées et à des mécanismes de coroutine efficaces. les programmes deviennent relativement faciles. Cet article présentera les technologies de synchronisation courantes dans Golang, notamment les verrous mutex, les variables de condition, les verrous en lecture-écriture et les opérations atomiques, et donnera des exemples de code spécifiques.

Introduction : 
À l’ère de l’information d’aujourd’hui, la plupart des applications doivent gérer un grand nombre de requêtes simultanées. Afin de garantir l'exactitude et les performances du programme, il est crucial de gérer correctement la concurrence. En tant que langage de programmation respectueux de la concurrence, Golang fournit des technologies de synchronisation très utiles qui peuvent nous aider à mettre en œuvre des programmes simultanés hautes performances.

1. Verrouillage Mutex
Le verrouillage Mutex est la technologie de synchronisation la plus basique, qui peut nous aider à obtenir un accès mutuellement exclusif aux variables partagées. Dans Golang, nous pouvons utiliser le package de synchronisation intégré pour implémenter les verrous mutex. Voici un exemple simple :

package main

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

var counter = 0
var mutex sync.Mutex

func increment() {
    mutex.Lock()
    counter++
    mutex.Unlock()
}

func main() {
    for i := 0; i < 1000; i++ {
        go increment()
    }

    time.Sleep(time.Second)

    fmt.Println("counter:", counter)
}

Dans le code ci-dessus, nous utilisons un verrou mutex mutex pour protéger l'accès à la variable partagée counter. Dans la fonction increment, on appelle d'abord la méthode Lock pour obtenir le verrouillage mutex, puis on incrémente le counter, et enfin on utilise Unlock La méthode libère le verrou mutex. Dans la fonction main, nous démarrons 1000 goroutines pour incrémenter counter en même temps, et enfin nous générons la valeur de counter. mutex来保护共享变量counter的访问。在increment函数中,我们首先调用Lock方法获取互斥锁,然后对counter进行自增操作,最后使用Unlock方法释放互斥锁。在main函数中,我们启动了1000个goroutine来同时对counter进行自增操作,最后输出counter的值。

二、条件变量
条件变量是一种允许goroutine等待或唤醒的同步机制。在Golang中,我们可以使用内置的sync包来实现条件变量。下面是一个简单的示例:

package main

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

var (
    counter = 0
    cond    = sync.NewCond(&sync.Mutex{})
)

func increment() {
    cond.L.Lock()
    counter++
    cond.Signal()
    cond.L.Unlock()
}

func decrement() {
    cond.L.Lock()
    for counter == 0 {
        cond.Wait()
    }
    counter--
    cond.L.Unlock()
}

func main() {
    for i := 0; i < 1000; i++ {
        go increment()
        go decrement()
    }

    time.Sleep(time.Second)

    fmt.Println("counter:", counter)
}

在上面的代码中,我们使用一个条件变量cond和一个互斥锁mutex来实现对共享变量counter的安全访问。在increment函数中,我们首先获取互斥锁,然后对counter进行自增操作,最后调用Signal方法唤醒一个等待在cond上的goroutine。在decrement函数中,我们首先获取互斥锁,然后检查counter的值是否为0,如果是则调用Wait方法等待,直到被唤醒,然后对counter进行自减操作。在main函数中,我们同时启动了1000个incrementdecrement函数,并最后输出counter的值。

三、读写锁
读写锁是一种允许多个goroutine并发读取共享资源,但只允许单个goroutine写入共享资源的同步机制。在Golang中,我们可以使用内置的sync包来实现读写锁。下面是一个简单的示例:

package main

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

var (
    counter = 0
    rwLock  = sync.RWMutex{}
)

func read() {
    rwLock.RLock()
    fmt.Println("counter:", counter)
    time.Sleep(time.Millisecond)
    rwLock.RUnlock()
}

func write() {
    rwLock.Lock()
    counter++
    time.Sleep(time.Millisecond)
    rwLock.Unlock()
}

func main() {
    for i := 0; i < 10; i++ {
        go read()
        go write()
    }

    time.Sleep(time.Second)
}

在上面的代码中,我们使用一个读写锁rwLock来保护共享变量counter的访问。在read函数中,我们使用RLock方法获取读锁,然后输出counter的值,并调用RUnlock方法释放读锁。在write函数中,我们使用Lock方法获取写锁,然后对counter进行自增操作,并调用Unlock方法释放写锁。在main函数中,我们同时启动了10个readwrite函数。

四、原子操作
原子操作是一种无需互斥锁就可以实现对共享变量的原子操作的同步机制。在Golang中,我们可以使用内置的atomic包来实现原子操作。下面是一个简单的示例:

package main

import (
    "fmt"
    "sync/atomic"
    "time"
)

var counter int32

func increment() {
    atomic.AddInt32(&counter, 1)
}

func main() {
    for i := 0; i < 1000; i++ {
        go increment()
    }

    time.Sleep(time.Second)

    fmt.Println("counter:", atomic.LoadInt32(&counter))
}

在上面的代码中,我们使用AddInt32函数对共享变量counter进行原子自增操作,并使用LoadInt32函数获取counter的值。在main函数中,我们同时启动了1000个increment函数,并最后输出counter

2. Variable de condition

La variable de condition est un mécanisme de synchronisation qui permet à goroutine d'attendre ou de se réveiller. Dans Golang, nous pouvons utiliser le package de synchronisation intégré pour implémenter des variables de condition. Voici un exemple simple :
rrreee

Dans le code ci-dessus, nous utilisons une variable de condition cond et un verrou mutex mutex pour implémenter la variable partagée Accès sécurisé à compteur. Dans la fonction increment, on obtient d'abord le verrou mutex, puis on incrémente le counter, et enfin on appelle la méthode Signal pour réveiller un signal en attente dans cond. Dans la fonction decrement, nous obtenons d'abord le verrouillage mutex, puis vérifions si la valeur du counter est 0. Si c'est le cas, appelons la fonction Wait méthode pour attendre jusqu'à ce qu'il soit réveillé, puis effectuer une opération d'auto-décrémentation sur counter. Dans la fonction main, nous démarrons 1000 fonctions increment et decrement en même temps, et enfin nous affichons la valeur du counter code> . <p></p>3. Verrouillage en lecture-écriture<ul>Le verrouillage en lecture-écriture est un mécanisme de synchronisation qui permet à plusieurs goroutines de lire des ressources partagées simultanément, mais qui permet uniquement à une seule goroutine d'écrire sur des ressources partagées. Dans Golang, nous pouvons utiliser le package de synchronisation intégré pour implémenter des verrous en lecture-écriture. Voici un exemple simple : <li>rrreee</li>Dans le code ci-dessus, nous utilisons un verrou en lecture-écriture <code>rwLock pour protéger l'accès à la variable partagée counter. Dans la fonction read, nous utilisons la méthode RLock pour obtenir le verrou de lecture, puis nous sortons la valeur du counter et appelons RUnlock libère le verrou de lecture. Dans la fonction <code>write, nous utilisons la méthode Lock pour obtenir le verrou en écriture, puis incrémentons le compteur et appelons Unlock code > La méthode libère le verrou en écriture. Dans la fonction <code>main, nous démarrons 10 fonctions read et write en même temps.
  • 4. Opérations atomiques Les opérations atomiques sont un mécanisme de synchronisation qui peut implémenter des opérations atomiques sur des variables partagées sans verrou mutex. Dans Golang, nous pouvons utiliser le package atomique intégré pour implémenter des opérations atomiques. Voici un exemple simple : 🎜rrreee🎜Dans le code ci-dessus, nous utilisons la fonction AddInt32 pour effectuer une opération d'incrémentation atomique sur la variable partagée counter et utilisons LoadInt32 La fonction obtient la valeur du counter. Dans la fonction main, nous démarrons 1000 fonctions increment en même temps, et enfin générons la valeur du counter. 🎜🎜Conclusion : 🎜Cet article présente les technologies de synchronisation courantes dans Golang, notamment les verrous mutex, les variables de condition, les verrous en lecture-écriture et les opérations atomiques, et donne des exemples de code spécifiques pour aider les lecteurs à mieux comprendre et utiliser ces technologies de synchronisation. programmes. Dans la programmation réelle, nous devons choisir une technologie de synchronisation appropriée en fonction de situations spécifiques et effectuer un contrôle de concurrence raisonnable pour améliorer les performances et la stabilité du programme. 🎜🎜Références : 🎜🎜🎜Site Web de langue chinoise Go (https://studygolang.com/)🎜🎜Site officiel de Go (https://golang.org/)🎜🎜

    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