亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

去信號處理

去信號處理

Go
慕的地8271018 2021-06-09 07:24:26
我對 Go 很陌生,并且一直在試圖弄清楚如何處理需要返回主循環的事件。在 C 中,我可以只返回函數,但似乎我不能在這里這樣做,至少用那個方法是這樣。我可以處理需要在 sigHandler() 中處理的信號,即 SIGINT 或 SIGTERM 但我需要在處理 SIGHUP 或 SIGUSR 時將調用返回到 main。在我下面的代碼中,一旦我發送掛斷信號,進程就會陷入等待模式。如果有人可以幫助我指導我如何正確設計信號處理以處理需要返回到第一個 goroutine 中的主代碼的調用,我將不勝感激。編輯我現在在 select{} 中的主 goroutine 中處理通道消息,但是當我發送 HUP 信號時,下面的代碼退出。這里的目標是重新加載配置并繼續正常執行。在主線代碼中,我有這個:go sigHandler()cs := make(chan bool, 1)go sigHandler(cs)// setup the http servererr := setupServer(addr, port)if err != nil {    fatal("Error setting up listening sockets")    os.Exit(1)}    select {    case quit := <-cs:        if quit {            logEvent(loginfo, sys, "Terminating..")            closeLog()            os.Exit(0)        } else {            logEvent(loginfo, sys, "Reloading configuration..")            }    }函數 sigHandler()func sigHandler(cs chan bool) {    c := make(chan os.Signal, 1)    signal.Notify(c, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)    signal := <-c    logEvent(lognotice, sys, "Signal received: "+signal.String())    switch signal {    case syscall.SIGINT, syscall.SIGTERM:        cs <- true    case syscall.SIGHUP:            cs <- false    }}
查看完整描述

2 回答

?
嚕嚕噠

TA貢獻1784條經驗 獲得超7個贊

你可以這樣做:


package main


import (

        "os"

        "os/signal"

        "syscall"

)


// We make sigHandler receive a channel on which we will report the value of var quit

func sigHandler(q chan bool) {

        var quit bool


        c := make(chan os.Signal, 1)

        signal.Notify(c, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)


        // foreach signal received

        for signal := range c {

                //      logEvent(lognotice, sys, "Signal received: "+signal.String())


                switch signal {

                case syscall.SIGINT, syscall.SIGTERM:

                        quit = true

                case syscall.SIGHUP:

                        quit = false

                }


                if quit {

                        quit = false

                        //              closeDb()

                        //              logEvent(loginfo, sys, "Terminating..")

                        //              closeLog()

                        os.Exit(0)

                }

                // report the value of quit via the channel

                q <- quit

        }

}


func main() {

        // init two channels, one for the signals, one for the main loop

        sig := make(chan bool)

        loop := make(chan error)


        // start the signal monitoring routine

        go sigHandler(sig)



        // while vat quit is false, we keep going

        for quit := false; !quit; {

                // we start the main loop code in a goroutine

                go func() {

                        // Main loop code here

                        // we can report the error via the chan (here, nil)

                        loop <- nil

                }()


                // We block until either a signal is received or the main code finished

                select {

                // if signal, we affect quit and continue with the loop

                case quit = <-sig:

                // if no signal, we simply continue with the loop

                case <-loop:

                }

        }

}

但是請注意,該信號會導致主循環繼續,但不會停止在第一個 goroutine 上的執行。


查看完整回答
反對 回復 2021-06-28
?
慕雪6442864

TA貢獻1812條經驗 獲得超5個贊

這是一種結構化事物來做你想做的事情的方法,分離關注點,這樣信號處理代碼和主代碼是分開的,并且很容易獨立測試。


如何實現 Quit 和 ReloadConfig 完全取決于您的程序 - ReloadConfig 可能會在通道上向正在運行的 goroutine 發送“請重新加載”值;它可能會鎖定互斥鎖并更改一些共享配置數據;或其他一些可能性。


package main


import (

    "log"

    "os"

    "os/signal"

    "syscall"

)


func main() {

    obj := &myObject{}

    go handleSignals(obj)

    select {}

}


type myObject struct {

}


func (obj *myObject) Quit() {

    log.Printf("quitting")

    os.Exit(0)

}


func (obj *myObject) ReloadConfig() {

    log.Printf("reloading configuration")

}


type MainObject interface {

    ReloadConfig()

    Quit()

}


func handleSignals(main MainObject) {

    c := make(chan os.Signal, 1)

    signal.Notify(c, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)

    for sig := range c {

        switch sig {

        case syscall.SIGINT, syscall.SIGTERM:

            main.Quit()

            return

        case syscall.SIGHUP:

            main.ReloadConfig()

        }

    }

}


查看完整回答
反對 回復 2021-06-28
  • 2 回答
  • 0 關注
  • 193 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號