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

19

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

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

    
задан Fabien 22.03.2013 в 10:27
источник
  • Этот вопрос полезен? Вот как я выполняю действия в конце выполнения. –  Denys Séguret 23.03.2013 в 14:41

3 ответа

27

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

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

Russ Cox :

  

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

     

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

     

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

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

  

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

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

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

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

    
ответ дан zzzz 22.03.2013 в 10:36
источник
  • Спасибо, это очень интересная тема. –  Fabien 22.03.2013 в 10:46
2

Если после прочтения всего этого (и, возможно, просмотра этого ), вы все равно хотите atexit - посмотрите Ссылка :)

    
ответ дан lazy1 22.03.2013 в 21:40
источник
  • Пожалуйста, обновите ссылку на GitHub –  ilyaigpetrov 01.01.2018 в 17:36
  • Выполнено, спасибо @ilyaigpetrov –  lazy1 02.01.2018 в 19:04
-1

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

    
ответ дан Thomas Kappler 22.03.2013 в 10:59
источник
  • Функции отсрочки от main работают только тогда, когда программа завершается завершением main, а не выходом из os.Exit, в отличие от исходного atexit, который также работает при вызове exit. –  guelfey 22.03.2013 в 13:47
  • И не работает, когда программа завершается с невосстановленной паникой. –  peterSO 22.03.2013 в 14:04
  • @peterSO Вы могли бы, однако, восстановиться в отложенной функции, так что это не реальный аргумент против отсрочки в основном. –  nemo 22.03.2013 в 19:42
  • @nemo: Перевод моего комментария на псевдокод: если паника и не восстанавливается, то не откладывайте ;. –  peterSO 22.03.2013 в 21:36
  • Он все равно не будет вызван, если используется os.Exit. –  0xcaff 30.04.2014 в 18:58