Ви не можете вірити, що кожен надісланий сигнал буде доставлений. Наприклад, ядро Linux "з’єднує" SIGCHLD, якщо процес займає тривалий час для обробки SIGCHLD із запущеного дочірнього процесу.
Щоб відповісти на іншу частину вашого запитання, сигнали потрапляють "у чергу" всередині ядра, якщо кількість різних сигналів надходить за занадто короткий інтервал.
Ви повинні використовувати sigaction()
для налаштування обробника сигналу з sa_sigaction
членом siginfo_t
, ретельно встановлюючи sa_mask
член siginfo_t
аргументу. Я думаю, що це означає принаймні замаскувати всі сигнали про "асинхрон". Згідно з довідковою сторінкою для Linux sigaction()
, ви також маскуєте сигнал, що обробляється. Я думаю, ви повинні встановити sa_flags
члена на SA_SIGINFO, але я не можу пригадати, чому у мене таке забобонство. Я вірю, що це отримає ваш процес обробника сигналів, який залишається встановленим без перегонових умов, і той, який не переривається більшістю інших сигналів.
Напишіть функцію обробника сигналів дуже, дуже обережно. В основному просто встановіть глобальну змінну, яка вказує на те, що сигнал потрапив, і решту процесу вирішують бажані дії для цього сигналу. Сигнали будуть маскуватися протягом найменшого часу таким чином.
Також ви хочете дуже ретельно перевірити код обробки сигналів. Помістіть це в невеликий тестовий процес і надішліть якомога більше сигналів SIGUSR1 і SIGUSR2, можливо, з 2 або 3 спеціальних програм передачі сигналів. Також змішайте деякі інші сигнали після того, як ви повірите, що ваш код може швидко та правильно обробляти SIGUSR1 та SIGUSR2. Підготуйтеся до складної налагодження.
Якщо ви використовуєте Linux та лише Linux, ви можете подумати про те, signalfd()
щоб створити дескриптор файлів, який ви можете select()
або опитувати для отримання цих сигналів. Використання signalfd()
може спростити налагодження.
signal(2)
наголошує, що ви уникаєте цієї плутанини, використовуючиsigaction(2)
натомість.