关于可重入函数的困惑

Confusion regarding reentrant functions

我对 "reentrant function" 的理解是,它是一个可以被中断(例如被中断服务程序或递归调用)并随后恢复的函数,这样函数的整体输出就不会受到任何影响被打扰了。

以下是来自维基百科的可重入函数示例 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;
}

然后假设主函数调用交换函数,但突然发生中断,那么输出肯定会失真,因为交换不正确,在我看来,这使该函数成为可能不可重入。

我的想法是对还是错?是不是我对重入的理解有误?

我从未听说过在中断服务例程上下文中使用的术语重入。通常 ISR(and/or 操作系统)有责任保持一致性——应用程序代码不需要知道中断可能做什么。

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

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

您问题的答案:

that the main function calls the swap function, but then suddenly an interrupt occurs, then the output would surely get distorted as the swap wouldn't be proper, which in my mind makes this function non-reentrant.

不是,不是,因为重入是(根据定义)相对于自我定义的。如果 isr 调用交换,另一个交换将是安全的。但是,swap 是线程不安全的。

正确的思维方式取决于重入和线程安全的精确定义(见,说Threadsafe vs re-entrant) 维基百科,相关代码的来源,选择了可重入函数的定义 "if it can be interrupted in the middle of its execution and then safely called again ("re-entered”),在其之前的调用完成之前”。