В обработчике сигналов сложно делать нетривиальные вещи, так как остальная часть программы находится в неизвестном состоянии. Большинство обработчиков сигналов просто устанавливают флаг, который позже проверяется и обрабатывается в другом месте программы.
Причина, по которой системный вызов не перезапускается автоматически:
Представьте себе приложение, которое получает данные из сокета посредством блокирующего и бесперебойного системного вызова recv ()
. В нашем сценарии данные поступают очень медленно, и программа долго находится в этом системном вызове. В этой программе есть обработчик сигнала для SIGINT
, который устанавливает флаг (который оценивается в другом месте), а SA_RESTART
устанавливает автоматический перезапуск системного вызова. Представьте, что программа находится в recv ()
, которая ожидает данных. Но никаких данных не поступает. Блокирует системный вызов. Программа теперь получает от пользователя ctrl - c . Системный вызов прерывается, и выполняется обработчик сигнала, который просто устанавливает флаг. Затем recv ()
перезапускается, все еще ожидая данных.Цикл событий застревает в recv ()
и не имеет возможности оценить флаг и корректно выйти из программы.
Если SA_RESTART
не установлен:
В приведенном выше сценарии, когда SA_RESTART
не установлен, recv ()
получит EINTR
вместо перезапуска. Системный вызов завершается и может быть продолжен. Конечно, программа должна затем (как можно раньше) проверить флаг (установленный обработчиком сигнала) и выполнить очистку или что-то еще.
Это требует обратных ссылок!
Если вы ссылаетесь на что-то, с чем вы уже сопоставили, и хотите сопоставить это снова, используйте обратные ссылки.
grep '(..)(.*\1){<n - 1>}' <file>
.*
соответствует любой последовательности символов (..)
соответствует любым двум символам \1
соответствует первой группе, в данном случае (..)
ближе к началу Замените <n - 1>
на длину последовательности минус один и <file>
на имя файла, который вы хотите найти (или опустите его, чтобы использовать stdin ).
Возможно, это не самое эффективное решение, но оно работает.