Я пишу API, использующий сокеты. В API я выделяю память для различных элементов. Я хочу убедиться, что закрываю сокеты и освобождаю память на случай, если появится сигнал, например Ctrl-C. В ходе исследования выяснилось, что free () не входит в список безопасных функций (сигнал man 7), поэтому я не могу освободить память внутри обработчика сигналов. Но я могу закрыть розетку нормально. Есть какие-нибудь мысли, как освободить память? Заранее благодарю вас за ваше время.
освобождение памяти внутри обработчика сигналов
Ответы (4)
В качестве альтернативы, не улавливайте сигнал и просто позвольте ОС обрабатывать очистку, как в любом случае она будет делать во время очистки процесса. Вы не освобождаете ресурсы, которые не привязаны напрямую к процессу, поэтому нет особой необходимости освобождать их вручную.
Одна техника (есть и другие):
- Пусть ваша программа запустит основной цикл обработки.
- Попросите ваш основной цикл обработки проверить флаг, чтобы увидеть, должен ли он «продолжать работать».
- Пусть ваш обработчик сигналов просто установит для флага "продолжить работу" значение false, но не завершает программу каким-либо иным образом.
- Попросите ваш основной цикл обработки выполнить очистку памяти перед выходом.
Это дает преимущество размещения как выделения, так и отмены выделения в блоках кода, которые вызываются с известной последовательностью. Это может быть находкой при работе с сетями взаимосвязанных объектов, и не будет состояния гонки между двумя потоками обработки, пытающимися вмешаться в один и тот же объект.
Не освобождайте в обработчике. Вместо этого укажите своей программе, что что-то нужно освободить. Затем определите это в своей программе, чтобы освободиться от основного контекста, а не от контекста сигнала.
Вы пишете библиотеку или приложение? Если вы пишете библиотеку, вам не нужно устанавливать обработчики сигналов, которые могут конфликтовать с вызывающим приложением. Задача приложения - обрабатывать такие сигналы, если оно того хочет, а затем делать соответствующие вызовы очистки в вашу библиотеку (извне контекста обработчика сигналов).
Конечно, даже если вы пишете приложение, нет причин обрабатывать SIGINT
, чтобы закрыть сокеты и освободить память. Единственные причины для обработки сигнала - это если вы не хотите завершать работу, или если у вас есть несохраненные данные или общее состояние (например, что-то в общей памяти или файловой системе) это необходимо очистить перед завершением. Освобождение памяти или закрытие файловых дескрипторов, которые используются исключительно вашим собственным процессом, не являются задачами, которые вам нужно выполнять при выходе.