2017-03-25 2 views
0

Je comprends que le comportement régulier d'un canal est qu'il se vide après une lecture. Est-il possible de conserver une valeur de canal sans tampon pour plusieurs lectures sans que la valeur ait été supprimée du canal? Par exemple, j'ai un goroutine qui génère une seule donnée pour plusieurs routines aller en aval à utiliser. Je ne veux pas avoir à créer plusieurs canaux ou utiliser un canal tamponné qui me demanderait de dupliquer les données sources (je ne sais même pas combien de copies j'aurai besoin). , Je veux effectivement être en mesure de faire quelque chose comme ce qui suit:Peut aller canal garder une valeur pour plusieurs lectures

main{ 
    ch := make(ch chan dType) 

    ch <- sourceDataGenerator() 
    for _,_ := range DynamicRange{ 
     go TargetGoRoutine(ch) 
    } 
    close(ch)  // would want this to remove the value and the channel 
} 
func(ch chan dType) TargetGoRoutine{ 
    targetCollection <- ch // want to keep the channel value after read 
} 

EDIT Certains estiment que c'est une double question. Peut-être, mais pas sûr. La solution ici semble simple à la fin comme l'a souligné n-canter. Tout ce dont il a besoin, c'est que chaque routine de "recyclage" des données soit remise en ligne après utilisation. Aucun des soi-disant «doublons» n'a fourni cette solution. Voici un exemple:

package main 
import (
    "fmt" 
    "sync" 
) 

func main() { 
c := make(chan string) 
var wg sync.WaitGroup 
    wg.Add(5) 

for i := 0; i < 5; i++ { 
    go func(i int) { 
     wg.Done() 
     msg := <-c 
     fmt.Printf("Data:%s, From go:%d\n", msg, i) 
     c <-msg 

    }(i) 
} 

    c <- "Original" 
    wg.Wait() 
    fmt.Println(<-c) 
} 

https://play.golang.org/p/EXBbf1_icG

+0

Un canal unbuffered ne tient pas de valeurs. Que diriez-vous d'ajouter la même valeur à un canal mis en mémoire tampon plusieurs fois? – JimB

+0

C'est une solution potentielle, mais comme je l'ai mentionné, je préfère ne pas avoir à pomper plusieurs valeurs. C'est parce que a) Je ne sais pas vraiment combien j'en aurai besoin. Donc je dois pomper en plus; b) les données sont plutôt volumineuses, ne veulent pas dupliquer autant :( – Bruce

+0

On dirait que vous voulez simplement utiliser un canal comme mutex autour d'une seule valeur, pourquoi ne pas utiliser un mutex? – JimB

Répondre

0

Vous pouvez readd valeur à la chaîne après avoir lu, mais tous vos gouroutines lirons séquentielle de valeur partagée et vous aurez besoin de quelques primitives de synchronisation pour la dernière goroutine ne pas bloquer. Pour autant que je sache, le seul cas où vous pouvez utiliser le canal unique pour la diffusion est la fermeture. Dans ce cas, tous les lecteurs seront avertis.

Si vous ne voulez pas dupliquer des données volumineuses, vous devriez peut-être utiliser une variable globale. Mais utilisez-le avec précaution, car il viole la règle golang: "Ne communiquez pas en partageant la mémoire, partagez la mémoire en communiquant."

Regardez aussi cette question How to broadcast message using channel

+0

Je pense que c'est la meilleure solution à ce jour.Un peu de duplication, mais au moins pas de duplication supplémentaire - Je ne dois pas créer plus que ce dont j'ai besoin.Merci! – Bruce