澄清GNUC库如何定义非进入函数

澄清GNUC库如何定义非进入函数,c,multithreading,reentrancy,C,Multithreading,Reentrancy,摘自: 例如,假设信号处理程序使用gethostbyname。此函数在静态对象中返回其值,每次重复使用相同的对象。如果信号恰好在调用gethostbyname期间到达,或者甚至在一次调用之后到达(程序仍在使用该值),则它将关闭程序请求的值 我看不出上面的场景是如何不可重入的。在我看来,gethostbyname是一个(只读)getter函数,它只从内存中读取(而不是修改内存)。为什么gethostbyname是不可重入的?正如这个词所说,可重入性是一个函数在线程中被调用时能够再次被调用的能力。您

摘自:

例如,假设信号处理程序使用gethostbyname。此函数在静态对象中返回其值,每次重复使用相同的对象。如果信号恰好在调用gethostbyname期间到达,或者甚至在一次调用之后到达(程序仍在使用该值),则它将关闭程序请求的值


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

正如这个词所说,可重入性是一个函数在线程中被调用时能够再次被调用的能力。您建议的场景就是执行重入的确切位置。当一个函数写入结构的返回缓冲区时,如果该函数有一些
静态
或全局变量(如
gethostbyname(3)
函数所做的),则另一个调用可以覆盖它以完全破坏第一次写入。当函数的执行中实例(被中断的实例,而不是被中断的实例)再次获得控制权时,它的所有数据都被中断的实例覆盖并销毁

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

如果两个线程调用同一段代码,并且所有参数和局部变量都存储在堆栈中,那么每个线程都有自己数据的副本,因此同时调用这两个线程是没有问题的,因为它们所接触的数据在不同的堆栈中。对于
静态
变量,即那些局部作用域、编译单元作用域或全局作用域,这是不会发生的(假设在调用同一段代码时会出现问题,因此一个调用可以访问任何地方,另一个调用也可以访问)

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

如果执行gethostbyname(x),调用将被信号捕获,并且信号处理程序执行gethostbyname(y),则调用将返回y的结果,因为只有一个静态返回。