Я хочу профилировать мою программу-демон, которая приостанавливает основной поток:
sigset_t signal_mask;
sigemptyset(&signal_mask);
sigaddset(&signal_mask, SIGTERM);
sigaddset(&signal_mask, SIGINT);
int sig;
sigwait(&signal_mask, &sig);
Все остальные потоки просто блокируют все сигналы.
Насколько я знаю, профилировщик использует SIGPROF
сигнал для его операций. Если я начну профилирование с таким кодом, выходной файл .prof будет пустым:
env CPUPROFILE = daemon.prof ./daemon
Как правильно обрабатывать сигналы в основном потоке и других потоках, чтобы включить профилирование? Или может проблема в другом?
Все остальные потоки просто блокируют все сигналы.
Вам просто нужно разблокировать SIGPROF
во всех темах (или в тех, которые вы хотите профилировать). Мы просто решали точно такую же проблему в многопоточном демоне.
Мне нужно увидеть больше вашего кода, но ваше заявление о том, что «все остальные потоки просто блокируют все сигналы» вызывает … сигналы.
Вы должны помнить, что большинство системных вызовов были созданы до того, как существовала концепция потоков. Обработка сигналов является одним из них. Таким образом, когда вы блокируете сигнал в ЛЮБОМ потоке, он, вероятно, блокируется для ВСЕХ потоков.
На самом деле, проверьте man-страницу signal (2):
The effects of signal() in a multithreaded process are unspecified.
Да, это печально, но это цена, которую вы должны заплатить за использование статистического профилировщика выборки с низкими издержками. И обойти это очень просто: просто удалите SIGPROF (или SIGALRM, если вы используете режим REAL) из своего набора маски сигнала, и все будет в порядке.
И вообще, если только вы не обязаны это делать, вы не должны выполнять маскирование сигналов на уровне процесса ни в чем, кроме основного потока … где «main» не обязательно означает поток, в котором выполняется MAIN (), но скорее, нить, которую вы считаете «боссом» всех остальных, по причинам, которые вы уже слишком ясно прояснили. 🙂
Вы также можете попробовать использовать Оболочка сигма-библиотеки библиотеки pthread pthread_sigmask, но мне неясно, насколько хорошо он работает в таких ситуациях, как дочерний поток, УДАЛЯЮЩИЙ запись из сигма-маски (pthreads наследуют сигма-маску pthread своего родителя).