Должна ли моя программа иметь возможность обрабатывать SIGINT?

#c #memory-management #error-handling #sigint

#c #управление памятью #обработка ошибок #sigint

Вопрос:

Должен ли я беспокоиться об обработке события, которое пользователь передает SIGINT в середине использования моей программы?

Рассматриваемая программа имеет дело с выделением и освобождением кучи, поэтому я обеспокоен тем, что такая ситуация может привести к утечке памяти. Когда я передаю SIGINT в середине использования программы, Valgrind сообщает:

 ==30173== Process terminating with default action of signal 2 (SIGINT)
==30173==    at 0x4ACC142: read (read.c:26)
==30173==    by 0x4A4ED1E: _IO_file_underflow@@GLIBC_2.2.5 (fileops.c:517)
==30173==    by 0x4A41897: getdelim (iogetdelim.c:73)
==30173==    by 0x109566: main (main.c:55)
==30173== 
==30173== HEAP SUMMARY:
==30173==     in use at exit: 1,000 bytes in 1 blocks
==30173==   total heap usage: 3 allocs, 2 frees, 3,048 bytes allocated
==30173== 
==30173== LEAK SUMMARY:
==30173==    definitely lost: 0 bytes in 0 blocks
==30173==    indirectly lost: 0 bytes in 0 blocks
==30173==      possibly lost: 0 bytes in 0 blocks
==30173==    still reachable: 1,000 bytes in 1 blocks
==30173==         suppressed: 0 bytes in 0 blocks
==30173== Rerun with --leak-check=full to see details of leaked memory
==30173== 
==30173== For lists of detected and suppressed errors, rerun with: -s
==30173== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
 

Комментарии:

1. Это действительно вопрос, на который вы должны ответить. Что вы хотите, чтобы программа делала, когда она получает SIGINT? Если вы рады, что он просто завершается, вам не нужно обрабатывать сигнал. И это не приведет к утечке памяти, поскольку все выделения очищаются при завершении процесса.

2. Если пользователь будет расстроен из-за необходимости повторно вводить ввод, который они пытались ввести в документ, который создает ваша программа, тогда вам, вероятно, нужно обработать прерывание. Если ваши пользователи не будут расстроены, тогда нет особой необходимости обрабатывать прерывания. Если вы обрабатываете прерывания, вам, вероятно, следует подумать о том, что произойдет, если программа получит SIGQUIT, SIGHUP, SIGPIPE, SIGTERM . Для всех этих случаев программа должна остановиться, но вам может потребоваться сохранить некоторое состояние. OTOH, многим простым программам не нужно явно обрабатывать какие-либо из них; действие по умолчанию в порядке. (Как сказал @kaylum.)

3. Я в порядке с обычным поведением SIGINT; меня беспокоит только заранее выделенная память. Происходит ли утечка памяти после получения сигнала? Если да, мне нужно обработать сигнал. Извините, если мой вопрос был немного запутанным.

Ответ №1:

Ответ зависит от операционной системы. Большинство современных операционных систем будут очищать память, выделенную вашим процессом, после его завершения (Windows, Linux, * nix в целом и многое другое). Обычно это просто часть системы изоляции и защиты памяти ОС, где каждый процесс получает свое собственное отображение виртуальной памяти, а физические страницы, соответствующие этому отображению, выделяются / освобождаются путем подсчета ссылок (завершенный / завершенный процесс уменьшит количество ссылок на свои отображенные физические страницы и освободит их, еслиони достигают нуля).

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

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

Комментарии:

1. Я стремлюсь к тому, чтобы моя программа была переносимой как для Windows, так и для Linux, поэтому я должен быть хорошим. Спасибо!