I heard printf() in C is not supposed to be used in ISR. Is it because it's a blocking call, or is it because it's not re-entrant?

If printf() is not re-entrant, then wouldn't it means that it can not be used for multi-thread program as well, unless it's 'synchronized' in some way?

Thanks,

有帮助吗?

解决方案

I think it might be all of those, and more. Typical printf() implementations can do dynamic (heap) memory allocation, which is generally not the fastest thing to be doing, and might also have issues with being non-re-entrant. The fastness thing can matter since you're typically not supposed to spend too much time in an interrupt service routine.

See this answer for a discussion about printf() and malloc().

其他提示

It shouldn't be in an ISR because it is not re-entrant nor thread-safe, but mainly because it is an extremely huge function which will lock up the whole program if you call it from an ISR, creating extreme interrupt jitter and instantly killing every hint of real-time performance in your program.

Huge, bombastic functions should not be in ISRs, no matter if they are thread-safe or not!

I'm going to assume that you mean interrupts, even though interrupt handlers in kernels usually have much more special limitations. The same argument applies to signal handlers, but it's usually simpler than the special restrictions on interrupt handlers. In case my assumption is wrong just replace "interrupt" with "signal" in the answer and it will apply.

Functions can be thread-safe without being signal/interrupt safe. If the function protects its internal state with a lock and then holds that lock when getting an interrupt there is no way for the interrupt handler to acquire that lock since the execution path that holds the lock is blocked by the interrupt. To release the lock you'd have to exit from the interrupt handler, resume execution of the thread until the lock is released and then go back to the interrupt handler. This is typically not really doable unless your kernel has implemented interrupt handlers as threads that can yield execution when waiting for locks.

A normal way to make a function both interrupt and thread safe is to block interrupts while holding the lock, but this is quite expensive and isn't done unless it's very necessary.

I heard printf() in C is not supposed to be used in ISR. Is it because it's a blocking call, or is it because it's not re-entrant?

More precisely because printf() is not a async-signal-safe function. See the list of async-signal-safe at the bottom of Signal Concepts.

If you call printf() from there, it may well work, maybe once or twice.. If it tried to block, that's pretty much a disaster since interrupt-handlers have no thread context.

If you link in multithreaded libraries on embedded stuff, printf() will get a mutex-style lock to ensure it's safe to call from multiple threads.

As the other posters say, just don't call such stuff from interrupt-handlers. Signaling semaphore units is always safe, IME. Other stuff only if specifically noted as such in the OS docs.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top