Heim  >  Artikel  >  Backend-Entwicklung  >  Wie stelle ich eine Zeitüberschreitung für den Bufio-Scanner ein, der in einer Schleife scannt?

Wie stelle ich eine Zeitüberschreitung für den Bufio-Scanner ein, der in einer Schleife scannt?

WBOY
WBOYnach vorne
2024-02-06 08:05:071061Durchsuche

Wie stelle ich eine Zeitüberschreitung für den Bufio-Scanner ein, der in einer Schleife scannt?

Frageninhalt

Ich verwende Golang, um einen Prozess zu starten und die Ausgabe zu überwachen. Der Prozess wird lange dauern und ich muss in der Lage sein, ein Signal zu senden, um ihn zu beenden.

Ich habe den folgenden Code, der in den meisten Fällen gut funktioniert. Aus bestimmten Gründen liefert der Prozess jedoch möglicherweise keine Ausgabe und die for-Schleife erhält eine scan()方法阻塞,无法接收来自processfinishchan-Meldung.

Gibt es eine einfache Möglichkeit, scan() 方法设置超时?我尝试了一个解决方案,在另一个 goroutine 中运行 scan() ,并使用另一个 select 从新的 goroutine 和超时通道接收,但考虑到外部 for 循环,是否会有越来越多的 goroutine 被 scan zu blockieren? 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()
    }
}


Richtige Antwort


Geht man vom Ergebnis von stdoutcmdobject.stdoutpipe() aus, dann sollte der Reader den Reader schließen und alle laufenden Lesevorgänge unterbrechen, während er auf den Abschluss des Prozesses wartet.

wait schließt die Pipe, nachdem der Befehl beendet wurde, sodass die meisten Aufrufer die Pipe nicht selbst schließen müssen.

Also müssen wir den Prozess in einer separaten Goroutine beenden und dann nach dem Beenden des Prozesses warten beobachten, wie es passiert, und den Reader schließen.

// 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()
}

Das obige ist der detaillierte Inhalt vonWie stelle ich eine Zeitüberschreitung für den Bufio-Scanner ein, der in einer Schleife scannt?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen