Я полагаю, что автор заинтересован не только в Ctrl + C и предлагает более широкое решение для Linux (для сигналов Windows см. x / sys / windows ):
package main
import (
"os"
"os/signal"
"syscall"
"fmt"
)
func getFireSignalsChannel() chan os.Signal {
c := make(chan os.Signal, 1)
signal.Notify(c,
// https://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html
syscall.SIGTERM, // "the normal way to politely ask a program to terminate"
syscall.SIGINT, // Ctrl+C
syscall.SIGQUIT, // Ctrl-\
syscall.SIGKILL, // "always fatal", "SIGKILL and SIGSTOP may not be caught by a program"
syscall.SIGHUP, // "terminal is disconnected"
)
return c
}
func exit() {
syscall.Kill(syscall.Getpid(), syscall.SIGTERM)
}
func main() {
exitChan := getFireSignalsChannel()
input, err := os.Open("input.txt")
if err != nil {
panic(err)
}
defer input.Close()
<-exitChan
fmt.Println("Exiting!")
return
// All main deferreds executed here even in case of panic.
// Non-main deferreds are not executed here.
}
P.S. Ни один из сигналов не обрабатывает os.Exit
.
При такой конфигурации на Ctrl + C или при получении другого сигнала программа переместит os.Signal
в канал exitChan
, что разблокирует операцию <-exitChan
, а функция main
продолжит выполнение на последние строки, затем возврат, затем выполнение отложенных функций.
Неосновные отсрочки
Для неосновных отсрочек вы можете:
- Использование https://github.com/tebeka/atexit
- Перемещение важных ресурсов в глобальный массив и освобождение их в основном отсроченном. Это решение не идеально, если вы не используете транзакцию: 1) создать ресурс, 2) добавить в массив, - который не должен прерываться при выходе. Также, я полагаю, должен быть предоставлен не одновременный доступ для чтения и записи к срезу.