C printf () в обработчике прерываний?
Я слышал, что printf () в C не должен использоваться в ISR. Это потому, что это блокирующий вызов, или потому, что это не повторный вход?
Если printf () не является повторным участником, то не означает ли это, что он также не может использоваться для многопоточной программы, если он не "синхронизирован" каким-либо образом?
спасибо,
5 ответов
Я думаю, что это может быть все это, и даже больше. Типичный printf()
реализации могут выполнять динамическое (кучное) выделение памяти, что, как правило, не является самым быстрым, и может также иметь проблемы с не-повторным входом. Быстрота вещь может иметь значение, так как вы, как правило, не должны тратить слишком много времени в рутине прерывания службы.
посмотреть ответ для обсуждения printf()
и malloc()
.
Я предполагаю, что вы имеете в виду прерывания, хотя обработчики прерываний в ядрах обычно имеют гораздо более специальные ограничения. Тот же аргумент применяется к обработчикам сигналов, но обычно он проще, чем специальные ограничения для обработчиков прерываний. В случае, если мое предположение неверно, просто замените "прерывание" на "сигнал" в ответе, и он будет применяться.
функции могут быть поток-безопасны без быть сейфом сигнала/прерывания. Если функция защищает свое внутреннее состояние с блокировкой, а затем удерживает эту блокировку при получении прерывания обработчик прерываний не может получить эту блокировку, так как путь выполнения, содержащий блокировку, блокируется прерыванием. Чтобы освободить блокировку, вам нужно выйти из обработчика прерываний, возобновить выполнение потока до тех пор, пока блокировка не будет освобождена, а затем вернуться к обработчику прерываний. Обычно это невозможно сделать, если ядро не реализовало обработчики прерываний в виде потоков, которые могут привести к выполнению ждут замки.
обычный способ сделать функцию прерывания и потокобезопасной-блокировать прерывания, удерживая блокировку, но это довольно дорого и не делается, если это не очень необходимо.
Он не должен быть в ISR, потому что он не является повторно входящим и потокобезопасным, но в основном потому что это чрезвычайно огромную функцию который заблокирует всю программу, если вы вызовете ее из ISR, создавая экстремальный прерывающий дрожание и мгновенно убивая каждый намек на производительность в реальном времени в вашей программе.
огромные, напыщенные функции не должны быть в ISRs, независимо от того, являются ли они потокобезопасными или нет!
Я слышал, что printf () в C не должен использоваться в ISR. Это потому, что это блокирующий вызов, или потому, что это не повторный вход?
точнее, потому что printf()
не является функцией асинхронного сигнала. См. список async-signal-safe в нижней части Понятия Сигнала.
Если вы вызываете printf () оттуда, это может хорошо работать, может быть, один или два раза.. Если он попытался заблокировать, это в значительной степени катастрофа, так как обработчики прерываний не имеют контекста потока.
Если вы связываетесь в многопоточных библиотеках на встроенных материалах, printf () получит блокировку в стиле мьютекса, чтобы обеспечить безопасность вызова из нескольких потоков.
Как говорят другие плакаты, просто не называйте такие вещи от обработчиков прерываний. Сигнальные семафорные устройства всегда безопасны, IME. Другой материал, только если специально отмечено как таковой в документах ОС.