中断处理程序中的C printf()?

我听说C中的printf()不应该用在ISR中。 是因为它是阻止呼叫,还是因为它不是可重入的?

如果printf()不是可重入的,那么它不会意味着它也不能用于multithreading程序,除非它以某种方式“同步”吗?

谢谢,

我认为可能是所有这些,甚至更多。 典型的printf()实现可以进行动态(堆)内存分配,这通常不是最快的事情,也可能存在不可重入的问题。 因为你通常不应该在中断服务程序中花费太多时间,所以牢固性很重要。

有关printf()malloc()的讨论,请参阅此答案 。

我将假设您的意思是中断,即使内核中的中断处理程序通常具有更多特殊限制。 相同的参数适用于信号处理程序,但它通常比对中断处理程序的特殊限制更简单。 如果我的假设是错误的,只需在答案中用“signal”替换“interrupt”,它就会适用。

function可以是线程安全的,而不是信号/中断安全。 如果函数通过锁保护其内部状态,然后在获得中断时保持该锁,则中断处理程序无法获取该锁,因为保持锁的执行路径被中断阻止。 要释放锁定,您必须退出中断处理程序,继续执行线程,直到锁定被释放,然后返回到中断处理程序。 除非你的内核已经将中断处理程序实现为可以在等待锁时产生执行的线程,否则这通常是不可行的。

使中断和线程安全的函数的正常方法是在保持锁定的同时阻止中断,但这是非常昂贵的,除非非常必要,否则不会这样做。

它不应该在ISR中,因为它不是可重入的,也不是线程安全的,但主要是因为它是一个非常庞大的函数 ,如果你从ISR调用它会锁定整个程序,产生极端的中断抖动并立即在程序中消除每一点实时性能。

巨大的,夸张的function不应该在ISR中,无论它们是否是线程安全的!

我听说C中的printf()不应该用在ISR中。 是因为它是阻止呼叫,还是因为它不是可重入的?

更准确地说,因为printf()不是异步信号安全function。 请参阅Signal Concepts底部的async-signal-safe列表。

如果你从那里调用printf(),它可能会工作,可能一次或两次..如果它试图阻止,那几乎是一个灾难,因为中断处理程序没有线程上下文。

如果你在嵌入式东西的multithreading库中链接,printf()将获得一个互斥式锁,以确保从多个线程调用是安全的。

正如其他海报所说,只是不要从中断处理程序中调用这些东西。 信令信号量单位总是安全的,IME。 其他东西只有在OS文档中特别注明时才会这样。