Maison  >  Article  >  développement back-end  >  Comment définir un délai d'attente pour le scanner bufio qui analyse en boucle ?

Comment définir un délai d'attente pour le scanner bufio qui analyse en boucle ?

WBOY
WBOYavant
2024-02-06 08:05:071075parcourir

Comment définir un délai dattente pour le scanner bufio qui analyse en boucle ?

Contenu de la question

J'utilise Golang pour démarrer un processus et surveiller le résultat. Le processus durera longtemps et je dois pouvoir envoyer un signal pour y mettre fin.

J'ai le code suivant qui fonctionne bien dans la plupart des cas. Mais pour certaines raisons, le processus peut ne produire aucun résultat et la boucle for recevra un message scan()方法阻塞,无法接收来自processfinishchan.

Existe-t-il un moyen simple de bloquer pour scan() 方法设置超时?我尝试了一个解决方案,在另一个 goroutine 中运行 scan() ,并使用另一个 select 从新的 goroutine 和超时通道接收,但考虑到外部 for 循环,是否会有越来越多的 goroutine 被 scan ? p>

// code that start the process...
scanner := bufio.NewScanner(stdout)

for {
    select {
    case <-processFinishChan: // send to this channel to terminate the process
        log.Println("Killing Process")
        err := cmdObject.Process.Kill()
        if err != nil {
            log.Printf("Error Killing: %v", err)
        } else {
            return
        }
    default:
        // default case, read the output of process and send to user.
        if !scanner.Scan() && scanner.Err() == nil {
            // reach EOF
            return
        }
        m := scanner.Bytes()

        WSOutChanHolder.mu.Lock()
        for _, ch := range WSOutChanHolder.data {
            ch <- m
        }
        WSOutChanHolder.mu.Unlock()
    }
}


Réponse correcte


En supposant le résultat de stdoutcmdobject.stdoutpipe(), le lecteur doit alors fermer le lecteur et interrompre toutes les lectures en cours en attendant la fin du processus.

wait fermera le canal après avoir vu la commande se terminer, donc la plupart des appelants n'auront pas besoin de fermer le canal eux-mêmes.

Nous devons donc tuer le processus dans un goroutine séparé, puis après avoir tué le processus, attendez regardez cela se produire et fermez le lecteur.

// code that start the process...
scanner := bufio.NewScanner(stdout)

go func() {
    <-processFinishChan: // send to this channel to terminate the process
    log.Println("Killing Process")
    err := cmdObject.Process.Kill()
    if err != nil {
        log.Printf("Error Killing: %v", err)
    } 

    cmdObject.Wait()
} ()

for {
    // default case, read the output of process and send to user.
    if !scanner.Scan() && scanner.Err() == nil {
        // reach EOF
        return
    }
    m := scanner.Bytes()

    WSOutChanHolder.mu.Lock()
    for _, ch := range WSOutChanHolder.data {
        ch <- m
    }
    WSOutChanHolder.mu.Unlock()
}

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