освобождение памяти внутри обработчика сигнала - PullRequest
5 голосов
/ 26 января 2012

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

Ответы [ 4 ]

6 голосов
/ 26 января 2012

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

4 голосов
/ 26 января 2012

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

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

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

2 голосов
/ 26 января 2012

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

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

2 голосов
/ 26 января 2012

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

...