Maison  >  Article  >  développement back-end  >  Où Golang doit-il se verrouiller ?

Où Golang doit-il se verrouiller ?

PHPz
PHPzoriginal
2023-04-25 15:10:44828parcourir

Dans la programmation Golang, les verrous sont un mécanisme important pour contrôler la concurrence. Toutefois, le verrouillage n'est pas requis dans tous les cas. Dans certains cas, le verrouillage augmentera la complexité du code et affectera les performances.

Alors, dans quelles circonstances les verrous doivent-ils être verrouillés dans la programmation Golang ?

  1. Plusieurs goroutines accèdent aux variables partagées

Lorsque plusieurs goroutines écrivent dans la même variable en même temps, elles doivent être verrouillées. En effet, la synchronisation dans Golang est effectuée via le mécanisme de canal et de verrouillage. Si le verrou n'est pas verrouillé, une condition de concurrence critique peut se produire, entraînant une incohérence des données.

Par exemple :

var count int
func addCount(value int) {
   count += value
}

Dans cet exemple, si plusieurs goroutines appellent la fonction addCount en même temps, cela entraînera countLa valeur de > est incorrecte. addCount函数,则会导致count的值不正确。

为了解决这个问题,可以使用sync.Mutex类型来加锁,例如:

var count int
var mu sync.Mutex
func addCount(value int) {
   mu.Lock()
   defer mu.Unlock()
   count += value
}

在这个例子中,使用mu.Lock()来锁定count,保证每个goroutine在进行操作时,能够独占变量。

  1. 多个goroutine进行读写操作

在多个goroutine进行读写操作的情况下,也需要加锁。这是因为在golang中,读和写都是原子操作,但是读写操作之间可能会存在交叉,导致数据的不一致性。

例如:

var m map[int]string
func writeToMap(key int, value string) {
   m[key] = value
}
func readFromMap(key int) string {
   return m[key]
}

在这个例子中,如果多个goroutine同时对map进行读写操作,则会导致竞态条件的产生,从而导致数据的不一致性。

为了解决这个问题,可以使用sync.RWMutex类型来加锁,例如:

var m map[int]string
var mu sync.RWMutex
func writeToMap(key int, value string) {
   mu.Lock()
   defer mu.Unlock()
   m[key] = value
}
func readFromMap(key int) string {
   mu.RLock()
   defer mu.RUnlock()
   return m[key]
}

在这个例子中,使用mu.RLock()mu.RUnlock()分别对读和写进行加锁和解锁。

  1. 多个goroutine之间的同步

在多个goroutine之间需要同步的情况下,也需要加锁。在golang中常常使用通道进行goroutine之间的同步,但是在通道不适用的情况下,需要使用锁机制。

例如:

var wg sync.WaitGroup
var mu sync.Mutex
var data []int
func worker() {
   defer wg.Done()
   for i := 0; i < 1000; i++ {
      mu.Lock()
      data = append(data, i)
      mu.Unlock()
   }
}
func main() {
   for i := 0; i < 10; i++ {
      wg.Add(1)
      go worker()
   }
   wg.Wait()
   fmt.Println(data)

在这个例子中,10个goroutine同时往data中加入1000个整数。由于data是一个共享变量,需要使用sync.Mutex

Afin de résoudre ce problème, vous pouvez utiliser le type sync.Mutex pour verrouiller, par exemple :

rrreee

Dans cet exemple, utilisez mu.Lock() pour verrouiller count pour garantir que chaque goroutine peut occuper exclusivement la variable lors de son fonctionnement. #🎜🎜#
    #🎜🎜#Plusieurs goroutines effectuent des opérations de lecture et d'écriture #🎜🎜##🎜🎜##🎜🎜#Dans le cas de plusieurs goroutines effectuant des opérations de lecture et d'écriture, vous avez également besoin pour ajouter un verrou. En effet, dans Golang, la lecture et l'écriture sont toutes deux des opérations atomiques, mais il peut y avoir un chevauchement entre les opérations de lecture et d'écriture, entraînant une incohérence des données. #🎜🎜##🎜🎜#Par exemple : #🎜🎜#rrreee#🎜🎜#Dans cet exemple, si plusieurs goroutines lisent et écrivent sur map en même temps, cela provoquera une condition de concurrence critique. ce qui entraîne une incohérence des données. #🎜🎜##🎜🎜#Afin de résoudre ce problème, vous pouvez utiliser le type sync.RWMutex pour verrouiller, par exemple : #🎜🎜#rrreee#🎜🎜#Dans cet exemple, utilisez mu.RLock() et mu.RUnlock() verrouillent et déverrouillent respectivement la lecture et l'écriture. #🎜🎜#
      #🎜🎜#Synchronisation entre plusieurs goroutines#🎜🎜##🎜🎜##🎜🎜#Lorsque la synchronisation est requise entre plusieurs goroutines, il est également nécessaire d'ajouter Lock. Les canaux sont souvent utilisés dans Golang pour synchroniser les goroutines, mais lorsque les canaux ne sont pas applicables, un mécanisme de verrouillage doit être utilisé. #🎜🎜##🎜🎜#Par exemple : #🎜🎜#rrreee#🎜🎜#Dans cet exemple, 10 goroutines ajoutent 1000 entiers aux data en même temps. Puisque data est une variable partagée, sync.Mutex doit être utilisé pour la verrouiller. #🎜🎜##🎜🎜#Pour résumer, dans la programmation Golang, les situations dans lesquelles des verrous doivent être utilisés incluent des situations dans lesquelles plusieurs goroutines accèdent à des variables partagées, plusieurs goroutines effectuent des opérations de lecture et d'écriture et une synchronisation est requise entre plusieurs goroutines. Lorsque vous utilisez des verrous, vous devez choisir le type de verrou approprié en fonction de la situation réelle pour garantir l'exactitude et 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!

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