освобождение памяти внутри обработчика сигналов

Я пишу API, использующий сокеты. В API я выделяю память для различных элементов. Я хочу убедиться, что закрываю сокеты и освобождаю память на случай, если появится сигнал, например Ctrl-C. В ходе исследования выяснилось, что free () не входит в список безопасных функций (сигнал man 7), поэтому я не могу освободить память внутри обработчика сигналов. Но я могу закрыть розетку нормально. Есть какие-нибудь мысли, как освободить память? Заранее благодарю вас за ваше время.


person Mike    schedule 26.01.2012    source источник
comment
Добавьте, что вы планируете выжить после сигнала?   -  person frankc    schedule 26.01.2012
comment
Нет, не совсем. Я просто хотел очистить память и сокеты до сбоя   -  person Mike    schedule 26.01.2012


Ответы (4)


В качестве альтернативы, не улавливайте сигнал и просто позвольте ОС обрабатывать очистку, как в любом случае она будет делать во время очистки процесса. Вы не освобождаете ресурсы, которые не привязаны напрямую к процессу, поэтому нет особой необходимости освобождать их вручную.

person jamessan    schedule 26.01.2012
comment
Я думаю, что то, что вы и Р. сказали, имеет смысл. Сначала позвольте приложению выполнять всю обработку сигналов (имеет смысл). Я не был уверен, закроет ли SIGINT или SIGSEGV сокеты или нет. Я был обеспокоен тем, что они оставят их открытыми, пока не пройдет какое-то время. Спасибо, что поправили меня. - person Mike; 26.01.2012
comment
У меня был плохой опыт с утечками ресурсов, которые были разрешены, потому что процесс очищал их при выходе. Я видел странные сбои, которые было трудно объяснить, и если по какой-то другой причине: это делает обслуживание сборки более раздражающим, если вы не хотите требовать никаких предупреждений (будь то от компилятора или статического анализатора) - person Brian Vandenberg; 05.08.2015

Одна техника (есть и другие):

  1. Пусть ваша программа запустит основной цикл обработки.
  2. Попросите ваш основной цикл обработки проверить флаг, чтобы увидеть, должен ли он «продолжать работать».
  3. Пусть ваш обработчик сигналов просто установит для флага "продолжить работу" значение false, но не завершает программу каким-либо иным образом.
  4. Попросите ваш основной цикл обработки выполнить очистку памяти перед выходом.

Это дает преимущество размещения как выделения, так и отмены выделения в блоках кода, которые вызываются с известной последовательностью. Это может быть находкой при работе с сетями взаимосвязанных объектов, и не будет состояния гонки между двумя потоками обработки, пытающимися вмешаться в один и тот же объект.

person Edwin Buck    schedule 26.01.2012
comment
Это API библиотеки, поэтому основной цикл здесь не применим. - person Mike; 26.01.2012
comment
Поскольку я создаю приложение, а не библиотеку, это решение идеально подходит для моей проблемы. Спасибо за ваш ответ! - person Z. Charles Dziura; 09.08.2012

Не освобождайте в обработчике. Вместо этого укажите своей программе, что что-то нужно освободить. Затем определите это в своей программе, чтобы освободиться от основного контекста, а не от контекста сигнала.

person Dave    schedule 26.01.2012

Вы пишете библиотеку или приложение? Если вы пишете библиотеку, вам не нужно устанавливать обработчики сигналов, которые могут конфликтовать с вызывающим приложением. Задача приложения - обрабатывать такие сигналы, если оно того хочет, а затем делать соответствующие вызовы очистки в вашу библиотеку (извне контекста обработчика сигналов).

Конечно, даже если вы пишете приложение, нет причин обрабатывать SIGINT, чтобы закрыть сокеты и освободить память. Единственные причины для обработки сигнала - это если вы не хотите завершать работу, или если у вас есть несохраненные данные или общее состояние (например, что-то в общей памяти или файловой системе) это необходимо очистить перед завершением. Освобождение памяти или закрытие файловых дескрипторов, которые используются исключительно вашим собственным процессом, не являются задачами, которые вам нужно выполнять при выходе.

person R.. GitHub STOP HELPING ICE    schedule 26.01.2012