golang data race

Le problème exposé dans ce sujet a été résolu.

Salut à tous,

J’ai un peu de temps libre et j’expérimente avec Go. j’ai fait un programme qui accepte toutes les connexions, et les gère dans une goroutine qui gère l’ajout de connexion à un pool et envois les messages en queue à ce même pool
Le pool est un simple tableau
Le problème c’est que j’accède de manière concurrente (parallèle?) à mon pool, est-ce que c’est une data-race ?

func handleCo(incommingConn <-chan *Connection, masterCom <-chan []byte) {
    log.Print("handling Conn")
    arrayConn := make([]*Connection, 0)


    //always add connection to the pool
    go func() {
        for {
            arrayConn = append(arrayConn, <-incommingConn)//block until there is a new co
            log.Printf("bot added")
        }
    }()

    //write msg from masterChan to
    go func() {
        for {
            for msg := range masterCom {
                for i := range arrayConn { 
                    _, werr := arrayConn[i].conn.Write(msg)
                    if werr != nil {
                        log.Fatal(werr)
                    }
                }
            }
        }
    }()
}

EDIT:

$: ~/go/src/echo/server$ go test -race

==================
WARNING: DATA RACE
Write at 0x00c000110000 by goroutine 15:
  echo/server.handleCo.func1()
      /Users/d3m0t3p/go/src/echo/server/echoServer.go:25 +0x122

Previous read at 0x00c000110000 by goroutine 16:
  echo/server.handleCo.func2()
      /Users/d3m0t3p/go/src/echo/server/echoServer.go:35 +0x71

Goroutine 15 (running) created at:
  echo/server.handleCo()
      /Users/d3m0t3p/go/src/echo/server/echoServer.go:23 +0x11b

Goroutine 16 (running) created at:
  echo/server.handleCo()
      /Users/d3m0t3p/go/src/echo/server/echoServer.go:31 +0x147

Apparemment il y a une data race, vous auriez une autre architecture à me proposer ou alors un moyen de syncroniser ça, je sais pas vraiment comment faire en go pour utiliser des mutex

+0 -0

salut,
désoler j’avais pas vu ta réponse,
avant j’avais justement un channel et une goroutine, mais j’ai decidé de changer les choses, maintenant j’ajoutes toutes les nouvelles connexions avant l’envoi de message, les deux se font pas de manière concurrente, de toute manière avec un system de mutex j’aurais eu des attentes entre les deux fonctions donc j’ai décidé de faire ça autrement :

func handleCo(incommingConn <-chan *Connection, masterCom <-chan []byte) {
    arrayConn := make([]*Connection, 0)

    adder := func() {
        length := len(incommingConn)
        for i := 0; i<length; i++ {
            arrayConn = append(arrayConn, <-incommingConn)
        }
    }

    for {
        adder()

        for msg := range masterCom {
            for i := range arrayConn { //use index, because range use a copy
                _, werr := arrayConn[i].conn.Write(msg)
                if werr != nil {
                    log.Fatal(werr)
                }
            }
        }
    }
}

l’appel à adder() est bloquant, mais je pense que c’est la meilleur solution même si ce n’est plus concurrent, de toute façon handleCo est lancé de manire concurrente donc ca devrait rester performant non ?

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte