Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在单线程环境中让函数可重入有什么意义?_C++_C_Multithreading_Reentrancy - Fatal编程技术网

C++ 在单线程环境中让函数可重入有什么意义?

C++ 在单线程环境中让函数可重入有什么意义?,c++,c,multithreading,reentrancy,C++,C,Multithreading,Reentrancy,在单线程环境中让函数可重入有什么意义 我明白,要使函数可重入,它需要能够被中断,由另一个线程输入,并在没有任何未定义或不希望的副作用的情况下恢复 我读了这个问题。但不清楚这在代码中究竟是如何发生的: 如果使用回调或递归函数,则单线程程序中可能存在重入问题 打断。它们与正常执行是异步的,在中断处理程序内和该处理程序外调用函数都会导致重新输入函数。在用户空间程序的操作系统中,您不直接处理中断,而是处理由操作系统触发的信号 在C++20中,在协程中调用函数可能会导致类似的重入 最后,递归是重入的另一种

在单线程环境中让函数可重入有什么意义

我明白,要使函数可重入,它需要能够被中断,由另一个线程输入,并在没有任何未定义或不希望的副作用的情况下恢复

我读了这个问题。但不清楚这在代码中究竟是如何发生的:

如果使用回调或递归函数,则单线程程序中可能存在重入问题


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

在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;
}
输出:

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

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

递归函数可以是可重入的单线程函数,而不使用中断。函数可以调用自身(可能使用中间函数)。另外,有中断的环境通常被描述为单线程的。我隐约记得,如果你在Windows中工作,你可以在等待计时器上调用程序,并发出信号,即使程序可能是单线程的。所以想象一下,如果你有一个计时器,它每半秒就响一次来调用你的计时器程序,但是你的计时器程序平均需要1秒才能完成。因此计时器进程需要是可重入安全的。@PaulMcKenzie是一个有趣的例子,但是它是单线程的这一事实不意味着它无论如何都必须等到函数调用完成后才能再次调用它吗?
inside operator() : 1
inside operator() : 0
something went wrong !!!