Не сохраняя список текущих потоков, я пытаюсь увидеть, что сигнал в реальном времени доставляется всем потокам в моем процессе. Моя идея состоит в следующем:
pthread_sigmask
) для себя и входит в цикл, многократно вызывая raise (sig)
, пока sigpending
не указывает, что сигнал в ожидании (не осталось потоков с заблокированным сигналом). Проблема, с которой я столкнулся, заключается в том, что pthread_sigmask
не соблюдается. Все работает правильно, если я запускаю тестовую программу под strace
(предположительно из-за другого времени планирования), но как только я запускаю ее в одиночку, отправитель получает свой собственный сигнал (несмотря на то, что заблокировал его ..?) и ни один из других потоков никогда не планируется.
Есть идеи, что может быть не так? Я пробовал использовать sigqueue
вместо raise
, проверяя маску сигнала, добавляя повсюду sleep
, чтобы убедиться, что потоки терпеливо ждут своих сигналов. и т. д. и теперь я в растерянности.
Изменить: Благодаря ответу psmears, я думаю, что понимаю проблему. Вот возможное решение.Обратная связь была бы отличной:
num_threads
сигналов процессу, затем разблокирует сигнал для себя. num_threads
, чтобы вернуться. num_threads
, затем снимает блокировку. Одна из возможных проблем заключается в том, что сигналы не будут помещены в очередь, если ядру не хватает памяти (похоже, у Linux есть такая проблема). Знаете ли вы, что sigqueue
надежно информирует вызывающего абонента, когда он не может поставить сигнал в очередь (в этом случае я буду зацикливаться до тех пор, пока он не будет успешным), или возможно, что сигналы будут потеряны без уведомления?
Редактировать 2: ] Кажется, сейчас он работает. Согласно документации для sigqueue
, он возвращает EAGAIN
, если ему не удается поставить сигнал в очередь. Но для надежности я решил просто продолжать вызывать sigqueue
до тех пор, пока не запустятся обработчики сигналов num_threads-1
, чередуя вызовы к sched_yield
после того, как я отправил num_threads-1
сигналов.
Во время создания потока возникла проблема состязания при подсчете новых потоков, но я решил это странным (ab) использованием блокировок чтения-записи. Создание потока - это «чтение», а широковещательный сигнал - «запись», поэтому, если нет потока, пытающегося выполнить широковещательную рассылку,он не создает никаких конфликтов при создании потока.