Читать книгу 📗 "Linux программирование в примерах - Роббинс Арнольд"
/* * Функции обратного вызова здесь просто отвечают на вызов. * В настоящем приложении они делали бы больше. */void callback1(void) { printf("callback1 calledn"); }void callback2(void) { printf("callback2 calledn"); }void callback3(void) { printf("callback3 calledn"); }/* main --- регистрация функций и завершение */int main(int argc, char **argv) { printf("registering callback1n"); atexit(callback1); printf("registering callback2n"); atexit(callback2); printf("registering callback3n"); atexit(callback3); printf("exiting nown"); exit(0);}Вот что происходит при запуске:
$ <b>ch09-atexit</b>registering callback1 /* Запуск главной программы */registering callback2registering callback3exiting nowcallback3 called /* Функции обратного вызова запускаются в обратном порядке */callback2 calledcallback1 calledКак показывает пример, функции, зарегистрированные с помощью
atexit()POSIX определяет функцию
_exit()exit()<stdio.h>_exit()#include <unistd.h> /* POSIX */void _exit(int status);Системе передается
statusexit()На практике функция
_Exit()_exit()_Exit()atexit()_exit()Время использовать
_exit()execexit()FILE*Например, предположим, что вы хотите запустить команду оболочки и хотите сами выполнить
forkexecchar *shellcommand = "...";pid_t child;if ((child = fork()) == 0) { /* порожденный процесс */ execl("/bin/sh", "sh", "-c", shellcommand, NULL); _exit(errno == ENOENT ? 127 : 126);}/* родитель продолжает */Проверка значения
errnoENOENTexecexit()atexit()• Определить небольшой набор значений статуса завершения, которые ваша программа будет использовать для сообщения этой информации вызывающему. Используйте для них в своем коде константы
#defineenum• Решить, имеет ли смысл наличие функций обратного вызова для использования с
atexit()main()• Использовать
exit()• Исключением является
main()returnexit()return 0main()• Использовать
_exit()_Exit()9.1.6. Использование статуса завершения порожденного процесса
Когда процесс заканчивается, нормальным ходом событий для ядра является освобождение всех его ресурсов. Ядро сохраняет статус завершения законченного процесса, также, как сведения о ресурсах, которые он использовал в своей работе, a PID продолжает считаться используемым. Такой завершившийся процесс называется зомби.
Родительский процесс, будь то первоначальный родитель или
init