Maison  >  Article  >  développement back-end  >  Pourquoi différentes longueurs de tableau sont-elles générées dans la programmation Golang simultanée ?

Pourquoi différentes longueurs de tableau sont-elles générées dans la programmation Golang simultanée ?

PHPz
PHPzavant
2024-02-09 11:42:29635parcourir

Pourquoi différentes longueurs de tableau sont-elles générées dans la programmation Golang simultanée ?

L'éditeur php Yuzai répondra à votre question sur la sortie de différentes longueurs de tableau dans la programmation Golang simultanée. En programmation simultanée, lorsque plusieurs goroutines exploitent une ressource partagée en même temps, des conditions de concurrence peuvent survenir, entraînant des résultats incertains. Lorsque plusieurs goroutines fonctionnent sur des tableaux en même temps, les longueurs des tableaux peuvent être différentes. En effet, l'ordre d'exécution entre les goroutines est incertain et les opérations de lecture et d'écriture peuvent se produire en même temps, ce qui entraîne une incohérence dans la longueur des tableaux. Pour résoudre ce problème, vous pouvez utiliser des mécanismes tels que des verrous mutex ou des canaux pour assurer la synchronisation et l'exécution séquentielle entre les goroutines, afin d'obtenir certains résultats.

Contenu de la question

J'écris un programme simple en Golang pour les tests de concurrence, mais je ne comprends pas capitalized la sortie différente de taille du tableau à chaque fois !

data := []rune{'a', 'b', 'c', 'd'}
var capitalized []rune

capit := func(r rune) {
    capitalized = append(capitalized, unicode.toupper(r))
    fmt.printf("%c done!\n", r)
}

fmt.printf("before: %c\n", capitalized)
for i := 0; i < len(data); i++ {
    go capit(data[i])
}
time.sleep(100 * time.millisecond)
fmt.printf("after: %c\n", capitalized)

Sortie :

b done! a done! d done! c done! after: [d b c a]
a done! d done! c done! b done! after: [d b a]
d done! a done! c done! b done! after: [b]
d done! a done! c done! b done! after: [a b c]
d done! b done! a done! c done! After: [B C]

Solution

go : Détecteur de course aux données

Vous avez une concurrence en matière de données.

$ go run -race racer.go
before: []
==================
warning: data race
write at 0x00c000012018 by goroutine 8:
  main.main.func1()
      racer.go:14 +0xc4
  main.main.func2()
      racer.go:20 +0x3e

previous read at 0x00c000012018 by goroutine 7:
  main.main.func1()
      racer.go:14 +0x44
  main.main.func2()
      racer.go:20 +0x3e

goroutine 8 (running) created at:
  main.main()
      racer.go:20 +0x199

goroutine 7 (running) created at:
  main.main()
      racer.go:20 +0x199
==================
a done!
==================
warning: data race
write at 0x00c000012018 by goroutine 9:
  main.main.func1()
      racer.go:14 +0xc4
  main.main.func2()
      racer.go:20 +0x3e

previous write at 0x00c000012018 by goroutine 10:
  main.main.func1()
      racer.go:14 +0xc4
  main.main.func2()
      racer.go:20 +0x3e

goroutine 9 (running) created at:
  main.main()
      racer.go:20 +0x199

goroutine 10 (running) created at:
  main.main()
      racer.go:20 +0x199
==================
d done!
b done!
c done!
after: [b c]
found 2 data race(s)
exit status 66
$

racer.go :

package main

import (
    "fmt"
    "time"
    "unicode"
)

func main() {
    data := []rune{'a', 'b', 'c', 'd'}
    var capitalized []rune

    capIt := func(r rune) {
        capitalized = append(capitalized, unicode.ToUpper(r))
        fmt.Printf("%c done!\n", r)
    }

    fmt.Printf("Before: %c\n", capitalized)
    for i := 0; i < len(data); i++ {
        go capIt(data[i])
    }
    time.Sleep(100 * time.Millisecond)
    fmt.Printf("After: %c\n", capitalized)
}

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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer