Практическое применение std::atexit

169
20 марта 2019, 19:20

Сегодня я узнал о существовании функции atexit. Читая мануалы б ней, не могу понять, насколько практически необходимо использовать эту функцию, если можно завершить программу банальным закрытием по крестику окна или завершению кода (если консоль)?

** @gil9red я видел этот пример по ссылке. Но до последнего не понимал, в каком случае можно применить эту функцию. Изучив примеры использованию по ссылкам на гитхабе, я пришёл к понимаю (как я сам ощущаю) способа применения atexit. Получается, что эта функция вызывается в любом случае, когда приложение завершается. То есть, реально можно реализовать сериализацию чего-либо, не прибегая к лишнему вызову из main() (ведь иногда можно попросту забыть сделать это :) ). Небольшой пример:

#include <iostream>
#include <string>
using namespace std;
void CloseProj()
{
  cout << "Выполнение закончено. Программа закрыта\n";
}
void EnterName()
{
  char name[20];
  int age;
  cout << "Пожалуйста, введите своё имя и возраст:\n"
       << "Имя: ";
  cin >> name;
  cout << "Введите свой возраст: \n"
       << "Возраст: ";
  cin >> age;
  cout << "Привёт, " << name << ". Тебе " << age << " лет!\n";
}
int main()
{
  atexit(CloseProj);
  EnterName();
}
Answer 1

Согласно источнику по ссылке функция int atexit( void ( * funcptr ) (void) );:

Функция atexit при завершении работы программы передает управление другой функции, которая будет выполняться на выходе.

Т.е. это возможность выполнить какие-то действия перед тем как программа будет завершена, например: отправить уведомление по сети, сохранить какие-то данные, и т.п. Тут уже будет зависеть от фантазии программиста.

Пример:

//пример использования функции atexit
#include <iostream>
#include <cstdio>
#include <cstdlib>
void funcExit1(void)
{
  std::cout << "Выход функции 1n";
}
void funcExit2(void)
{
    std::cout << "Выход функции 2n";
}
int main()
{
  atexit(funcExit1); // при выходе из программы, запустить функцию funcexit1
  atexit(funcExit2); // при выходе из программы, запустить функцию funcexit2
  std::cout << "завершение main функцииn";
  return 0;
}

Консоль:

завершение main функции
Выход функции 2
Выход функции 1

Полное описание:

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

Если функция atexit была вызвана более одного раза, то порядок выполнения функций, передаваемых в качестве аргумента, будет обратным. Такой принцип работы функции основан на работе стека, т.е. последняя вызванная функция будет выполняться первой.

Одна единственная функция может быть зарегистрирована на выполнение более одного раза, после завершения работы программы.

Реализация С++ должна поддерживать регистрацию по меньшей мере 32 atexit функций.

Примеры практического использования из популярных репозиториев с++:

  • https://github.com/apple/swift
  • https://github.com/nlohmann/json
  • https://github.com/pytorch/pytorch
  • https://github.com/opencv/opencv: [1], [2], [3]
  • https://github.com/electron/electron
  • https://github.com/chromium/chromium
Answer 2

Вывод полной логистики на экран, хранимой внутри программы, состоянии переменных (для debugg-инга).

// g++ -Wall -Wpedantic atexit.cpp
# include <cstdlib>
# include <iostream>
int globalX;
void exc(){
  std::cerr<<"globalX="<<globalX<<"\n";}
void  f(){
  globalX = 777 ;
  std::exit(1);
  globalX = 666 ;  }
int main(){
  if(std::atexit(exc)){
    std::cerr<<"main:std::atexit(exc)\n";
    return 1;}
  f();
  return 0;}
Answer 3

Может быть профессионалам где нибудь и понадобится вызвать эту функцию, поскольку постольку(сужу чисто логически, но не уверен так ли это...) есть многочисленные старые коды, да и программировать приходится коллективно, и у каждого свой стиль, собственная абстракция и уровень знаний. С++ постоянно прогрессирует, появляются все новые и новые средства (классы, функции, библиотеки, приложения), но это не значит, что все что было раньше нужно выбросить. Те же массивы уже кажутся лишными, когда есть совершенно безопасные контейнеры (лично я не пользуюсь массивами, хотя часто пишу программы), но ведь они же используются по разным сооброжениям и нуждам. Не нужным могут выглядеть также очень многие(если не все) функции языка С, например такие как printf, puts..., но иногда ими пользоваться удобно, да и не все люди склонны быстро отбрасывать привычный стиль и годами накопленные знания. В С++ можно уже обходится без простых указателей и пользоваться только умными указательями, но задавать вопрос: "так зачем же нам обычные указатели?" не стоит, и т.д. и т.п. Так что std::atexit пока еще существует в старых кодах и может встречаться в новых каких то, и если она есть в стандарте, означает ее нужность, но в любом случаи хорошо быть информированным. Просто знать, но не думать как ее использовать, потому что нынче очень много возможностей для того, чтобы обходиться без этой функции(те же деструкторы) а думать как хорошо проектировать и написать хороший, читабельный, удовлетворяющий требованиям заказчика код. И чем больше у вас информации о существующих инструментах, предоставленными стандартом и приложением, тем больше вариантов для решения задачи у вас возникнут... P.S. Если плохо изложил или не то что надо, то заранее извеняюсь( все таки русский не мой родной язык и программирование не моя профессия). Просто захотел поделиться своим мнением по этому поводу.

Answer 4

На практике я использовал atexit в программах, работающих с shared memory для удаления сегментов (shmctl) при завершении процесса.

Кстати, аналогичная, но к сожалению, depricated функция on_exit
(Portable application should avoid this function, and use the standard atexit(3) instead.)
на мой взгляд более удобна.

READ ALSO
Вызвать метод из одной активности в другой

Вызвать метод из одной активности в другой

Не могли бы, пожалуйста, подсказать, как правильно вызвать (если это возможно) метод из одной активности в другой? Я прочитал за наследование,...

154
Изменить fragment 2 из fragment 1

Изменить fragment 2 из fragment 1

Условия: Имеется приложение с Activity и тремя fragment'ами, которые можно листать смахивая влево - вправо как страницы (Этот эффект осуществляется...

164
Как вытащить пароли с Google Chrome используя Java? [закрыт]

Как вытащить пароли с Google Chrome используя Java? [закрыт]

Хотелось бы создать приложение которое вытащит пароли с Google Chrome которые лежат тут C:\Users\elnur\AppData\Local\Google\Chrome\User Data\Default

141
Надо сохранить информацию о том сколько раз пользователь подсмотрел ответ

Надо сохранить информацию о том сколько раз пользователь подсмотрел ответ

Есть небольшое приложение: надо хранить информацию о том сколько раз был подсмотрен ответ(ответ находится во второй Активити, при возвращении...

127