Подтвердить что ты не робот

В go, есть ли способ выполнить код при завершении программы?

Я знаю, что вы можете определять функции с именем init в любом пакете, и эта функция будет выполнена до main. Я использую это, чтобы открыть мой файл журнала и мое соединение с БД.

Есть ли способ определить код, который будет выполняться, когда программа закончится, либо потому, что она достигает конца функции main, либо потому, что она была прервана? Единственный способ, о котором я могу думать, - это вручную вызывать дефисную функцию terminate для каждого пакета, используемого основным, но это довольно многословный и подверженный ошибкам.

4b9b3361

Ответ 1

Функциональность C atexit была рассмотрена разработчиками Go, и идея ее принятия была отвергнута.

Из одной из связанных потоков в golang-nut:

Russ Cox:

Atexit может иметь смысл в однопоточных, недолговечных программ, но я скептически отношусь к тому, что он имеет место в многопоточный сервер. Я видел много программ на С++, которые зависают на выходе, потому что они используют глобальные деструкторы, которые действительно не нужны и эти деструкторы очищают и освобождают память, которая будет исправлена ​​операционной системой в любом случае, если бы только программа могла получить доступ к системному вызову выхода. По сравнению со всей этой болью, нужно вызвать Flush, когда вы один с буфером кажется вполне разумным и необходимо в любом случае для правильного выполнения длительных программы.

Даже игнорируя эту проблему, atexit вводит еще больше потоки управления, и вы должны отвечать на такие вопросы, как все остальные горуты останавливаются перед обработчиками atexit бег? Если нет, то как им избежать вмешательства? Если да, то что, если у одного есть блокировка, которой нужен обработчик? И дальше и дальше.

Я вовсе не склонен добавить Atexit.

Ян Лэнс Тейлор:

Единственный полностью надежный механизм - это программа-оболочка, которая вызывает реальной программы и выполняет очистку при завершении реальной программы. Что верно на любом языке, а не только на Go.

В моем несколько неоформленном мнении os.AtExit не является отличной идеей. это неструктурированный объект, который заставляет вещи произойти при выходе программы время в непредсказуемом порядке. Это приводит к странным сценариям, таким как программы, которые занимают много времени, чтобы выйти, операция, которая должна быть очень быстро. Это также приводит к странным функциям, таким как функция C _exit, который более или менее означает функции выхода, но не выполняющие-atexit-функции.

Тем не менее, я думаю, что специальная функция выхода, соответствующая init функция - интересная идея. У этого была бы структура, которая os.AtExit недостает (а именно, функции выхода выполняются в обратном порядке, когда запускаются функции init).

Но функции выхода не помогут вам, если ваша программа будет убита ядро или сбой, потому что вы вызываете некоторый код C, который получает сегментацию нарушение.

Ответ 2

Если после прочтения всего этого (и, возможно, просмотрено this), вы все равно хотите atexit - посмотрите https://github.com/tebeka/atexit:)

Ответ 3

В общем, я согласен с jnml ответом. Если вы все еще хотите это сделать, вы можете использовать defer в функции main(), например: http://play.golang.org/p/aUdFXHtFOM.