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

时间:2012-10-03 07:58:41

标签: c multithreading interrupt-handling

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

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

谢谢,

5 个答案:

答案 0 :(得分:6)

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

有关printf()malloc()的讨论,请参阅this answer

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:1)

它不应该在ISR中,因为它不是可重入的,也不是线程安全的,但主要是因为它是一个极其庞大的功能会锁定整个程序,如果你从ISR调用它,创建极端的中断抖动,并立即杀死程序中的每一个实时性能。

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

答案 3 :(得分:0)

  

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

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

答案 4 :(得分:0)

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

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

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