В настоящее время я изучаю Go и ZeroMQ, и в этом духе я пытаюсь предоставить примеры Go для Zguide. У меня возникли трудности с примером прерывания. Я не уверен, каким будет идиоматический способ решения проблемы.
В настоящее время у меня есть следующее решение: я создаю канал, который получает сигнал SIGINT. Когда это происходит, я пишу логическое значение на другом канале, который используется в основном цикле для прерывания. Проблема в том, что Recv блокируется, цикл никогда не проверяет условие цикла. Я обхожу проблему, передавая константу NOBLOCK в Recv. Но я чувствую, что есть лучший способ, поскольку Recv должен возвращать EINTR при прерывании (насколько я могу судить, это не так). Вы, читатели, гораздо лучше подготовлены к ответу на этот вопрос, чем я, как вы думаете?
Для вашего удобства код, который у меня есть до сих пор:
package main
import (
"os/signal"
"os"
"fmt"
zmq "github.com/alecthomas/gozmq"
)
func listenForSignals(exit_channel chan bool) {
signal_channel := make(chan os.Signal)
signal.Notify(signal_channel)
<- signal_channel
fmt.Println("stopping")
exit_channel <- true
}
func main() {
exit := make(chan bool)
exit_signal := false
go listenForSignals(exit)
context, _ := zmq.NewContext()
defer context.Close()
socket, _ := context.NewSocket(zmq.REP)
defer socket.Close()
socket.Bind("tcp://*:5555")
for exit_signal == false {
select {
case exit_signal = <- exit:
fmt.Println("W: interrupt received, killing server...")
default:
msgbytes, err := socket.Recv(zmq.NOBLOCK)
fmt.Printf("%s.\n", string(msgbytes))
}
}
}
Изменить несколько упростил код на основе отзывов