Comment savoir qu'un canal en mémoire tampon est plein? Je ne sais pas être bloqué lorsque le canal en mémoire tampon est plein, mais j'ai choisi de supprimer l'élément envoyé au canal en mémoire tampon.
Vous pouvez utiliser select
instruction avec une valeur par défaut. Dans le cas où il n'est pas possible de faire l'un des cas, comme l'envoi à un canal complet, l'instruction fera la valeur par défaut:
package main
import "fmt"
func main() {
ch := make(chan int, 1)
// Fill it up
ch <- 1
select {
case ch <- 2: // Put 2 in the channel unless it is full
default:
fmt.Println("Channel full. Discarding value")
}
}
Sortie:
Canal plein. Jeter la valeur
Aire de jeux: http://play.golang.org/p/1QOLbj2Kz2
Vérifier sans envoyer
Il est également possible de vérifier le nombre d'éléments mis en file d'attente dans un canal en utilisant len(ch)
, comme indiqué dans Go spécifications . Ceci en combinaison avec cap
nous permet de vérifier si un canal est plein sans envoyer de données.
if len(ch) == cap(ch) {
// Channel was full, but might not be by now
} else {
// Channel wasn't full, but might be by now
}
Notez que le résultat de la comparaison peut être invalide au moment où vous entrez le bloc if
au lieu de cela, je choisis de supprimer l'élément envoyé sur le canal en mémoire tampon.
Cela s'appelle "canal débordant", et vous trouvez la réponse d'ANisus implémentée dans eapache/channels/overflowing_channel.go
:
for elem := range ch.input {
// if we can't write it immediately, drop it and move on
select {
case ch.output <- elem:
default:
}
}
close(ch.output)
Mais ce projet eapache/canaux implémente également d'autres stratégies:
OverflowingChannel
implémente l'interface Channel
d'une manière qui ne bloque jamais l'écrivain.OverflowingChannel
lorsque son tampon est pleinPour le comportement opposé (éliminer l'élément le plus ancien, pas le plus récent), voir
RingChannel
.
Un autre exemple utile sur lequel je suis tombé était cette implémentation astucieuse of Ring Buffer .
La citation de la source:
L'idée est simple: connectez deux canaux tamponnés via un Goroutine qui transmet les messages du canal entrant au canal sortant. Chaque fois qu'un nouveau message ne peut pas être placé sur le canal sortant, retirez un message du canal sortant (c'est-à-dire le plus ancien message du tampon), supprimez-le et placez le nouveau message dans le canal sortant nouvellement libéré.
Découvrez cette version C ainsi ...