Как завершить программу go из goroutine


Я пытаюсь реализовать некоторое нетипичное поведение в интерфейсе командной строки, написанном в go.

У меня есть функция, которая работает в течение длительного времени, и я хочу иметь функцию очистки, которая работает, когда кто-то ctrl-c выходит из этой функции.

Вот макет кода:

func longRunningFunction() {
    //some set up stuff
    sigs := make(chan os.Signal, 1)
    signal.Notify(sigs, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)

    go func() {
        <-sigs
        fmt.Println("Got an interrupt")
        cleanup()
    }()
    //the long-running command
    fmt.Println("the end")
}

В обычном случае использование ctrl-c не потребуется, и функция завершится нормально. (Из-за этого я не могу иметь что-то (например, канал) в главном потоке, который блокирует, пока очистка горутина закончил.) Однако в том случае, если пользователь нажимает ctrl-c, я хотел бы немедленно завершить программу, не печатая "конец" (и в идеале не завершая длительную команду).

Это не происходит прямо сейчас. В настоящее время вывод командной строки выглядит следующим образом:

...
//long-running-command's output
^CGot an interrupt
//cleanup code's output
$
//more of long-running-command's output
the end

Я запутался на нескольких фронтах - почему программа все еще печатает после возвращения запроса, и почему "конец" все еще печатается? Как я могу избежать такого поведения? Это сценарий даже возможен в го? Спасибо!

1 3

1 ответ:

Вы продолжаете выполнение после обработчика сигнала. Если вы хотите выйти из процесса, позвоните os.Exit:

go func() {
    <-sigs
    fmt.Println("Got an interrupt")
    cleanup()
    os.Exit(2)
}()