簡體   English   中英

如何使用Go啟動,監視和終止進程

[英]How to start and monitor and kill process with Go

我正在Go中編寫一個程序,它應該打開一個可移植的瀏覽器到一個給定的頁面並監視它,這樣如果瀏覽器關閉,它應該自動重新打開。 程序退出時也應該關閉瀏覽器。

到目前為止,我已經設法在用戶關閉瀏覽器時重新打開瀏覽器,但是我無法關閉它。

這是我的代碼:

package browser

import (
    "fmt"
    "os/exec"

    log "github.com/sirupsen/logrus"
)

type iBrowserHandler interface {
    Start(processListener chan bool) error
    Stop() error
    KillProcess() error
}

type browserHandler struct {
    cmd            *exec.Cmd
    pathToChromium string
    pdvEndpoint    string
}

func newBrowserHandler(pathToChromium string, pdvEndpoint string) iBrowserHandler {
    b := &browserHandler{}
    b.pathToChromium = pathToChromium
    b.pdvEndpoint = pdvEndpoint

    return b
}

func (b *browserHandler) Start(processListener chan bool) error {
    endpoint := fmt.Sprintf("--app=%s", b.pdvEndpoint)

    b.cmd = exec.Command(b.pathToChromium, endpoint, "--kiosk")
    err := b.cmd.Run()
    if err != nil {
        log.WithError(err).Error("Error with the browser process")
        processListener <- false
    } else {
        processListener <- true
    }

    return err
}

func (b *browserHandler) Stop() error {
    err := b.cmd.Process.Release()
    if err != nil {
        log.WithError(err).Fatal("Error shutting down chromium")
    }

    return err
}

func (b *browserHandler) KillProcess() error {
    err := b.cmd.Process.Kill()
    if err != nil {
        log.WithError(err).Fatal("Error killing chromium process")
    }

    return err
}

這是我用來啟動瀏覽器的功能:

var handler iBrowserHandler

func init() {
    var pathToChromium string
    var c = config.GetInstance()
    var os = runtime.GOOS

    if os == "windows" {
        pathToChromium = "chromium-browser\\ChromiumPortable.exe"
    } else {
        pathToChromium = "chrome"
    }

    handler = newBrowserHandler(pathToChromium, c.GetConfig().PDVUrl)
}

func StartBrowser(done chan bool) {
    browserProcessListener := make(chan bool)
    defer close(browserProcessListener)
    go handler.Start(browserProcessListener)

    var tryReopenBrowser = true
    for {
        select {
        case <-browserProcessListener:
            if tryReopenBrowser {
                log.Warn("Browser process is stopped. Attempting to restart")
                go handler.Start(browserProcessListener)
            } else {
                log.Warn("Browser process is stopped. Will not attempt to restart")
            }

        case <-done:
            log.Info("Shutting down browser")
            tryReopenBrowser = false
            handler.KillProcess()
            return

        default:
        }
    }
}

程序啟動時,我調用StartBrowser()函數。 瀏覽器啟動后,它會一直監聽它是否已關閉( cmd.Run()函數會阻止線程的執行,直到進程完成)。

如果瀏覽器已關閉,則我的程序會嘗試重新打開它。

如果程序收到停止信號,它會嘗試關閉瀏覽器。 我嘗試使用cmd.Process.Release()cmd.Process.Kill()命令,但兩者都不關閉瀏覽器。 有沒有其他方法可以做到這一點?

我找到了答案! 問題是Go cmd.Process.Kill()命令只停止父進程,而不是子進程,所以我不得不通過操作系統手動終止這些進程。

由於我在Windows上,我的KillProcess()方法現在看起來像這樣:

func (b *browserHandler) KillProcess() error {
    log.Info("Killing browser process")
    kill := exec.Command("taskkill", "/T", "/F", "/PID", strconv.Itoa(b.cmd.Process.Pid))
    err := kill.Run()
    if err != nil {
        log.WithError(err).Error("Error killing chromium process")
    }
    log.Info("Browser process was killed")

    return err
}

致謝:這個主題WindowsUnix系統的答案。

而不是cmd.Run()使用cmd.Start() 看到這個

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM