【问题标题】:What is the significance of having a function reentrant in a single-threaded environment?在单线程环境中具有可重入函数的意义是什么?
【发布时间】:2021-03-30 10:48:36
【问题描述】:

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

我了解,要使函数可重入,它需要能够被中断、被另一个线程进入并恢复,而不会产生任何未定义或不希望的副作用。

我读到了这个问题Threadsafe vs re-entrant。但目前尚不清楚这如何在代码中实际发生:

如果您使用回调或递归函数,您可能会在单线程程序中遇到重入问题。

【问题讨论】:

  • 递归函数可以是可重入和单线程的,无需使用中断。
  • 该函数可以调用自身(可能带有一个中间函数)。此外,具有中断的环境通常被描述为单线程。
  • 据我隐约记得,如果您在 Windows 中工作,您可以让在等待计时器上调用的过程发出信号,即使该程序可能是单线程的。所以想象一下,如果你有一个每半秒关闭一次的定时器来调用你的定时器程序,但它平均需要 1 秒来完成你的定时器程序。所以计时器过程需要是可重入安全的。
  • @PaulMcKenzie 有趣的例子,但它是单线程的事实是否意味着它无论如何都必须等到函数调用完成才能再次调用它?

标签: c++ c multithreading reentrancy


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

    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 !!!
    

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

    【讨论】:

      猜你喜欢
      • 2011-06-01
      • 1970-01-01
      • 2020-05-30
      • 1970-01-01
      • 2015-01-12
      • 1970-01-01
      • 2014-07-28
      • 2021-11-13
      • 1970-01-01
      相关资源
      最近更新 更多