Maison > développement back-end > Golang > Comment puis-je remplacer de manière fiable les délais d'attente de Goroutine à l'aide des canaux dans Go ?

Comment puis-je remplacer de manière fiable les délais d'attente de Goroutine à l'aide des canaux dans Go ?

Susan Sarandon
Libérer: 2024-12-14 20:56:21
original
218 Les gens l'ont consulté

How Can I Reliably Override Goroutine Timeouts Using Channels in Go?

Remplacement des délais d'attente dans les goroutines avec des canaux

Dans Golang, lors de l'utilisation de goroutines et de canaux pour des tâches asynchrones, il est possible de spécifier des délais d'attente pour garantir que les opérations ne sont pas suspendues indéfiniment. Cependant, dans certains scénarios, le cas d'expiration peut ne pas être exécuté comme prévu.

Considérez l'extrait de code suivant :

package main

import (
    "fmt"
    "time"
)

func main() {
    c1 := make(chan int, 1) // Buffered channel with capacity 1

    go func() {
        for {
            time.Sleep(1500 * time.Millisecond) // Sleep for 1.5 seconds
            c1 <- 10 // Send value to channel
        }
    }()

    go func() {
        for {
            select {
            case i := <-c1:
                fmt.Println(i)
            case <-time.After(2000 * time.Millisecond):
                fmt.Println("TIMEOUT") // Not executed
            }
        }
    }()

    fmt.Scanln() // Wait for user input
}
Copier après la connexion

Dans ce code, nous avons deux goroutines : une qui envoie périodiquement une valeur vers un canal tamponné c1 et une autre qui sélectionne parmi c1 avec un délai d'attente de 2 secondes. Cependant, le cas d'expiration ("TIMEOUT") n'est jamais imprimé.

La raison en réside dans la nature des canaux mis en mémoire tampon et dans la manière dont les délais d'attente sont gérés. Dans ce scénario, la goroutine qui envoie des valeurs à c1 remplira continuellement le canal toutes les 1,5 secondes. Par conséquent, l'instruction select de la deuxième goroutine recevra toujours une valeur de c1 avant l'expiration du délai d'attente.

Pour résoudre ce problème et garantir que le cas de délai d'attente est exécuté, nous devons créer le canal de délai d'attente à l'extérieur la boucle de sélection. Cela l'empêche d'être supprimé à chaque fois qu'une valeur est reçue de c1 :

timeout := time.After(2000 * time.Millisecond) // Create timeout channel only once
for {
    select {
    case i := <-c1:
        fmt.Println(i)
    case <-timeout:
        fmt.Println("TIMEOUT")
    }
}
Copier après la connexion

Avec cette modification, l'instruction select continuera à sélectionner à partir de c1, mais si aucune valeur n'est reçue dans le délai spécifié, l'instruction select continuera à sélectionner à partir de c1, mais si aucune valeur n'est reçue dans le délai spécifié, Le cas "TIMEOUT" sera exécuté.

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!

source:php.cn
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal