简体   繁体   中英

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

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

I understood that for a function to be reentrant it needs to be able to be interrupted, entered by another thread, and resume without having any undefined or undesired side effects.

I read this question Threadsafe vs re-entrant . But it's not clear how can this actually happen in code:

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

Suppose we put multi-threading aside. This function can be said to be non re-entrant:

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

    inside_function = false;
}

Without recursion and callbacks this isn't an issue. Though once you add recursion the non-re-entrancy of the function matters:

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;
}

Suppose do some stuff depends on inside_function == true , then this recursion fails (output is 1 0 ). Note that this is a contrived example for illustration and with callbacks the issue is not always that obvious:

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);
}

Output:

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

In a single threaded environment thread-safety is not an issue, but re-entrancy is when recursion or callbacks are used.

Interrupts. They are asynchronous with the normal execution and calling a function both in an interrupt handler and outside of that handler results in the function being re entered. Within an operating system in a user space program, you don't deal with interrupts directly, but with signals triggered by the operating system.

In C++20, calling functions within coroutines may cause similar re entrancy.

Lastly, recursion is another form of re entrancy.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM