阐明 GNU C 库如何定义不可重入函数

Clarifying how GNU C Library defines nonreentrant functions

取自:https://www.gnu.org/software/libc/manual/html_node/Nonreentrancy.html

For example, suppose that the signal handler uses gethostbyname. This function returns its value in a static object, reusing the same object each time. If the signal happens to arrive during a call to gethostbyname, or even after one (while the program is still using the value), it will clobber the value that the program asked for.

我看不出上面的场景是如何不可重入的。在我看来,gethostbyname 是一个(只读)getter 函数,它仅从内存中读取(而不是修改内存)。为什么 gethostbyname 不可重入?

顾名思义,可重入性是一个函数在另一个线程中被调用时能够被再次调用的能力。您提出的方案是执行重入的确切位置。假设该函数有一些 static 或全局变量(如 gethostbyname(3) 函数所做的那样)由于结构的 return 缓冲区正在由一个写入,另一个调用可以完全覆盖它破坏第一个写作。当函数的 in execution 实例(被中断的,而不是中断的)再次获得控制权时,它的所有数据都被中断的实例覆盖,并销毁了它。

解决此中断问题的常用方法是在函数执行时禁用中断。这样它就不会被对自身的新调用打断。

如果两个线程调用同一段代码,所有的参数和局部变量都存储在栈中,每个线程都有一份自己的数据,所以同时调用两者是没有问题的,因为他们接触的数据在不同的堆栈中。 static 变量不会发生这种情况,即那些局部作用域、编译单元作用域或全局作用域(认为问题出在调用同一段代码时,所以一个调用可以访问的任何地方,另一个调用也可以访问)

静态数据,如缓冲区(查看 stdio 缓冲包)等,通常意味着例程不可重入。