Maison  >  Article  >  développement back-end  >  Complications de concurrence dans le passage des paramètres de la fonction Golang

Complications de concurrence dans le passage des paramètres de la fonction Golang

王林
王林original
2024-04-13 18:54:01485parcourir

Lorsque des Goroutines simultanées modifient des paramètres partagés, les règles suivantes existent pour le passage des paramètres de la fonction Go : Passer par valeur : une copie est transmise à la fonction, et la modification de la copie n'affecte pas la valeur d'origine. Passer par référence : un pointeur est passé à une fonction et la modification de la valeur du pointeur modifie également la valeur d'origine. Lors du passage par référence, plusieurs Goroutines modifiant simultanément les paramètres peuvent entraîner des complications de concurrence. Dans les scénarios de simultanéité de données partagées, le passage par référence doit être utilisé avec prudence et en conjonction avec des mesures de contrôle de simultanéité appropriées.

Complications de concurrence dans le passage des paramètres de la fonction Golang

Complications de concurrence dans le passage des paramètres de la fonction Go

Dans Go, les paramètres de la fonction peuvent être transmis par valeur ou par référence. Lors du passage par valeur, une copie du paramètre est transmise à la fonction, tandis que lors du passage par référence, les modifications apportées au paramètre sont reflétées dans la fonction appelante.

Cependant, dans un environnement concurrent, ce modèle de transmission de paramètres peut entraîner des complications de concurrence, car plusieurs Goroutines s'exécutant simultanément peuvent modifier le même paramètre en même temps.

Pass by value

func modifyInt(i int) {
    i++ // 只修改 i 变量的副本
}

func main() {
    i := 0
    go modifyInt(i)
    fmt.Println(i) // 输出 0(原始值)
}

Dans le cas du pass by value, bien que la fonction modifyInt() modifie la copie de i qui lui est passée, la fonction appelante L'original La variable i n'est pas affectée. modifyInt() 函数修改了传递给它的 i 的副本,但调用函数中的原始 i 变量不受影响。

按引用传递

func modifyIntPointer(i *int) {
    *i++ // 修改 i 变量的实际值
}

func main() {
    i := 0
    go modifyIntPointer(&i)
    fmt.Println(i) // 输出 1(修改后的值)
}

在按引用传递的情况下,对指向原始 i 变量的指针参数的修改将反映在调用函数中。这可能会导致并发并发症,因为多个 Goroutine 可能会同时修改同一参数。

实战案例

考虑以下读写锁案例,它保护对共享数据的并发访问。

type MutexMap struct {
    m map[string]int
    mu sync.Mutex // 互斥锁
}

func (m *MutexMap) Get(key string) int {
    m.mu.Lock() // 加锁
    defer m.mu.Unlock() // 解锁(延迟执行)
    return m.m[key]
}

func (m *MutexMap) Set(key string, value int) {
    m.mu.Lock()
    defer m.mu.Unlock()
    m.m[key] = value
}

如果 MutexMapm

Pass by reference

rrreee

En cas de passage par référence, les modifications de l'argument pointeur pointant vers la variable i d'origine seront reflétées dans la fonction appelante. Cela peut entraîner des complications de concurrence, car plusieurs Goroutines peuvent modifier le même paramètre en même temps.

Cas pratique🎜🎜Considérez le cas de verrouillage en lecture-écriture suivant, qui protège l'accès simultané aux données partagées. 🎜rrreee🎜Si le champ m de MutexMap est passé par référence, plusieurs Goroutines peuvent se verrouiller en même temps, entraînant un blocage. 🎜🎜Conclusion🎜🎜Dans un environnement concurrent, il est important de comprendre les modèles de passage des paramètres de fonction et leur impact potentiel sur les données partagées. Le passage par valeur est généralement plus sûr, tandis que le passage par référence doit être utilisé avec prudence et en conjonction avec des contrôles de concurrence appropriés. 🎜

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