Мне нужно работать с модулем регистрации, который можно вызывать из разных мест в большом проекте. Проблема в том, что иногда модуль может вызываться из кода, выполняемого внутри обработчика сигнала. Обычно модуль регистрации включает данные времени, используя localtime() и strftime(), но, конечно, эти вызовы не являются безопасными для асинхронного сигнала и могут вызывать взаимоблокировки при вызове из обработчика сигнала. Есть ли способ (в системе GNU/Linux) определить, выполняется ли в настоящее время мой код в контексте обработчика сигнала, кроме, например, если каждый обработчик сигнала задает флаг во время обработки? Я думаю, что было бы лучше упростить наши обработчики сигналов, но в этом случае у меня нет выбора, где можно вызвать модуль регистрации. Было бы неплохо, если бы я мог проверить и просто опустить информацию о временной отметке, если модуль вызывается во время обработки сигнала.Есть ли способ проверить, находится ли я в обработчике сигналов?
ответ
Прежде всего, ваш вопрос («Я в обработчике сигналов?») Не имеет четко определенного ответа. Рассмотрим следующий код:
#include <setjmp.h>
#include <signal.h>
jmp_buf jb;
int foo(int s)
{
longjmp(jb,1);
}
int main()
{
if (setjmp(jb)) {
puts("Am I in a signal handler now, or not?");
return 0;
}
signal(SIGINT, foo);
raise(SIGINT);
}
С учетом сказанного, есть техника, которую вы можете использовать, чтобы ответить на этот вопрос существенным образом для многих программ. Выберите сигнал, который вы не собираетесь использовать, и добавьте его в sa_mask
для всех сигналов, которые вы обрабатываете, устанавливая обработчики сигналов с помощью sigaction
. Затем вы можете использовать sigprocmask
, чтобы проверить текущую сигнальную маску, и если ваш назначенный сигнал находится в сигнальной маске, это означает, что обработчик сигнала был вызван и еще не вернулся (возврат будет восстанавливать исходную сигнальную маску).
Это интересный момент о longjmp (или siglongjmp); Я должен подумать об этом и о том, что на самом деле означает быть в обработчике сигналов. Моя основная забота - знать, могу ли я быть в какой-то другой части кода, которая могла бы удерживать блокировку, и поскольку такого рода вещи не были бы безопасными для setjmp/longjmp, я вообще не использую функции jmp они могут вызвать эту проблему. Мне нравится предложение sigaction/sa_mask, хотя это похоже на то, что я точно ищу. –
Есть ли у вашей системы sigpending
? Я не знаю, каково поведение этой функции во время обработчика сигнала. Однако, если он возвращает флаг установки, вы можете быть пессимистичным и пропускать асинхронные-небезопасные вызовы, если какие-либо сигналы ожидаются.
Я думаю, что sigpending установлен только до подачи сигнала. После ввода обработчика сигнала сигнал не устанавливается как «ожидающий». –
Самый простой способ заключается в регистрации через (называемый) канал (запись до PIPE_MAX является атомарной) или через UDP-сокет (idem). Порог сообщения может быть задан функцией, генерирующей сообщение. Конечно, вам понадобится процесс, который на самом деле читает и обрабатывает сообщения, но может храниться вне контекста обработчика сигналов.
КСТАТИ: не нужен отдельный процесс, чтобы получать сообщения, вы можете отправить сообщения на свой собственный процесс и добавить (конец считывания) трубу к fd_set (учитывая программу сидит в цикл выбора или опроса) или периодически опроса.
Кроме того, вы пытаетесь сделать это извращенным. Вы не перегружаетесь от обработчика сигнала (см. Sigjump et.al). Кроме того, функции stdio не считаются безопасными по сигналу (они называются malloc() и т. Д.) – wildplasser
К сожалению, я прокомментировал программу R., которая должна была быть извращенной. Сожалею! – wildplasser
Мне нравится этот ответ в том, что он дает хороший способ сделать что-то, но я действительно не хочу добавлять отдельный процесс и отправлять все сообщения журнала через канал, если мне это не нужно.Я все еще хочу, чтобы был простой способ определить, был ли я в обработчике сигналов; кажется, что ОС не должно быть сложно знать. –
- 1. Есть ли способ проверить, находится ли параметр в хранимой процедуре?
- 2. Есть ли способ проверить, находится ли пользователь в Windows XP?
- 3. Есть ли способ проверить, могу ли я безопасно использовать Page.IsValid?
- 4. Есть ли способ проверить, есть ли хост?
- 5. Есть ли способ проверить, сколько сообщений находится в очереди MSMQ?
- 6. В .NET MVC есть ли простой способ проверить, находится ли я на домашней странице?
- 7. Есть ли способ проверить, закрыт ли TextWriter?
- 8. Есть ли способ проверить unique_together?
- 9. Есть ли способ проверить, создан ли SVG?
- 10. Есть ли способ проверить, включена ли TLS?
- 11. Есть ли способ проверить, используется ли файл?
- 12. Есть ли способ проверить, установлен ли будильник?
- 13. Есть ли способ проверить, открыт ли файл?
- 14. Есть ли способ проверить метаданные?
- 15. Есть ли способ проверить, зашифрован ли файл?
- 16. Есть ли способ, чтобы проверить, есть ли массив в массиве?
- 17. Использование 'this' в обработчике событий Android. Есть ли способ лучше?
- 18. linux/glibc. Можно ли использовать fprintf в обработчике сигналов?
- 19. Есть ли способ программно определить, находится ли фотография в фокусе?
- 20. Можно ли проверить форму в обработчике отправки?
- 21. Есть ли способ проверить клиента с curl?
- 22. Есть ли способ проверить, есть ли текст между узлами
- 23. Приостановление выполнения нитей в обработчике сигналов
- 24. Есть ли способ проверить, существует ли удаленное изображение? PHP
- 25. Есть ли способ проверить, имеет ли класс основной метод?
- 26. Есть ли принятый/принятый способ проверить, находится ли человек (номер телефона) в списке контактов?
- 27. LibGDX: есть ли способ проверить, находится ли окно в фокусе? * SOLVED *
- 28. Есть ли более быстрый способ проверить, находится ли число в пределах интервала?
- 29. Есть ли способ проверить, находится ли местоположение (долгота, широта) в пределах предопределенного многоугольника?
- 30. Есть ли способ проверить, не находится ли пользователь в настоящее время?
Часто плохой идеей иметь системные вызовы от обработчиков сигналов ... вы уверены, что вы здесь защищены? – JXG
Да, это проблема. Я хочу избежать небезопасных системных вызовов *, если * Я в обработчике сигналов, но имею их, если код вызывается, когда я не в обработчике сигналов. –