关于可重入函数的困惑

时间:2015-10-14 22:30:02

标签: interrupt reentrancy

我对“可重入函数”的理解是它是一个可以被中断的函数(例如,通过ISR或递归调用),然后恢复,使得函数的整体输出不会受到中断的任何影响

以下是维基百科https://en.wikipedia.org/wiki/Reentrancy_(computing)

中可重入函数的示例
int t;

void swap(int *x, int *y)
{
    int s;

    s = t; // save global variable
    t = *x;
    *x = *y;

    // hardware interrupt might invoke isr() here!
    *y = t;
    t = s; // restore global variable
}

void isr()
{
    int x = 1, y = 2;
    swap(&x, &y);
}

我在想,如果我们像这样修改ISR会怎么样:

void isr()
{
    t=0;
}

然后,让我们说主函数调用交换函数,然后突然发生中断,然后输出肯定会因为交换不正确而失真,这在我的脑海里使这个函数非折返。

我的想法是对还是错?我对重入的理解是否存在错误?

2 个答案:

答案 0 :(得分:1)

我从未听过在中断服务程序的上下文中使用的术语re-entrancy。 ISR(和/或操作系统)通常负责保持一致性 - 应用程序代码不需要知道中断可能做什么。

函数是可重入的通常意味着它可以同时从多个线程调用 - 或者通过递归(直接或通过更复杂的调用链)自身调用 - 并且仍然保持内部一致性。

对于可重入的函数,它们通常必须避免使用静态变量,当然也要避免调用其他本身不可重入的函数。

答案 1 :(得分:1)

你的问题的答案:

  

主函数调用交换函数,但突然发生中断,然后输出肯定会因交换不正确而失真,这在我看来会使这个函数不可重入。

不是,它没有,因为(根据定义)re-entrancy是针对self定义的。如果isr调用swap,则另一个swap是安全的。但是,交换是线程不安全的。

正确的思维方式取决于重新进入和线程安全的精确定义(参见Threadsafe vs re-entrant) 维基百科是相关代码的来源,它选择了可重入函数的定义为“如果它可以在执行过程中被中断,然后在其先前的调用完成执行之前再次安全地调用(”重新输入“)。