在单线程环境中具有可重入函数的意义是什么?

What is the significance of having a function reentrant in a single-threaded environment?

单线程环境下函数可重入的意义是什么?

我明白,要使一个函数可重入,它需要能够被中断、被另一个线程进入并在没有任何未定义或不需要的副作用的情况下继续。

我读了这个问题Threadsafe vs re-entrant。但不清楚这在代码中是如何发生的:

you can have reentrance problems in a single-threaded program if you use callbacks or recursive functions.

中断。它们与正常执行是异步的,并且在中断处理程序中和在该处理程序之外调用一个函数会导致重新进入该函数。在用户 space 程序的操作系统中,您不直接处理中断,而是处理操作系统触发的信号。

在C++20中,在协程中调用函数可能会导致类似的重入。

最后,递归是另一种形式的重入。

假设我们把多线程放在一边。这个函数可以说是不可重入的:

void bar() {
    static bool inside_function;
    inside_function = true;
    
    assert (inside_function == true)

    inside_function = false;
}

如果没有递归和回调,这不是问题。虽然一旦你添加递归函数的不可重入性很重要:

void foo(bool repeat = true) {
    static bool inside_function;
    inside_function = true;
    
    if (repeat) foo(false);

    // do some stuff
    // assert( inside_function == true )
    std::cout << inside_function << "\n";

    inside_function = false;
}

假设do some stuff依赖于inside_function == true,那么这个递归失败(输出是1 0)。请注意,这是一个用于说明的人为示例,并且对于回调,问题并不总是那么明显:

struct Foo {
    bool inside = false;
    void operator()(Foo& f,bool call = true) {
        inside = true;

        if(call) f(*this,false);

        std::cout << "inside operator() : " << inside  << "\n";
        if (inside == false) std::cout << "something went wrong !!!\n";             

        inside = false;
    }
};

int main() {
    Foo f;
    f(f);
}

输出:

inside operator() : 1
inside operator() : 0
something went wrong !!!

在单线程环境中,线程安全不是问题,但在使用递归或回调时可重入。