C语言 重入性与全局变量

jvlzgdj9  于 2023-01-16  发布在  其他
关注(0)|答案(1)|浏览(198)

我看到说全局变量更新使函数不可重入,这是有道理的。但我不明白为什么做本地复制和恢复可以解决它。
下面是一个例子:

int global_n = 10;

1 void foo()
2 {
3    int local_n = global_n;
4    global_n *= 10;
5    if (global_n < 100) {
6       printf("double digits\n");
7    } else {
8       printf("not double digits\n");
9    }
10   printf("%d\n", global_n);
11   global_n = local_n;
12 }

假设foo()的第一次运行执行了第4行,现在global_n为100,并且该运行被另一次foo()的运行中断,并且第二次运行的第4行使global_n为1000,因此该函数仍然是不可重入的。
我说的对吗?
参考:这是GNU libc的一句话,让我问了上面的问题--如果你想在一个处理程序中调用一个修改内存中某个特定对象的函数,你可以通过保存和恢复那个对象来保证它的安全。
我用全局变量替换了"内存"。

chhkpiq4

chhkpiq41#

当他们说
如果你想在一个处理程序中调用一个函数来修改内存中的一个特定对象,你可以通过保存和恢复那个对象来保证它的安全。
它们意味着您可以编写 * 信号处理程序 *,以便通过在信号处理程序 * 中保存和恢复该对象 * 来安全地调用函数。
不能通过保存和还原函数中的全局变量或其他共享状态来使不可重入函数成为可重入函数。如果函数修改了共享状态,则它是不可重入的。
信号处理程序不应该调用不可重入的函数。但是信号处理程序本身不需要是可重入的。信号掩码将(通常)防止信号处理程序被重新输入。除非信号处理程序被分配给多个信号而不屏蔽其他信号,或者除非它从掩码中删除其信号。当然,只有一个信号处理程序可以用特定的共享状态来玩这个游戏,除非屏蔽了其它信号TO的接收。
因此,如果信号处理程序需要调用一个修改共享状态的函数,并且确切地知道正在修改的是什么共享状态,那么可以在调用不可重入函数之前将该共享状态保存在信号处理程序中,然后在不可重入函数返回之后将其恢复到信号处理程序中。
这是否可取是另一个问题。我不建议这样做。事实上,我倾向于让尝试这样做的程序的代码评审失败。有太多的极端情况需要检查。但是YMMV。

相关问题