Joh*_*ger 5 c java-native-interface gcc
我正在为C库编写Java绑定,因此正在使用JNI.甲骨文规定,合理,这与Java使用的机库应与多线程感知的编译器进行编译.
JNI的文档给出具体的例子,对gcc,这个多线程意识要求应通过定义一个宏来满足_REENTRANT或_POSIX_C_SOURCE.这对我来说似乎很奇怪. _REENTRANT并且_POSIX_C_SOURCE是功能测试宏.GCC和POSIX文档描述了它们在定义符号和使声明可见方面的效果,正如我对任何特征测试宏所期望的那样.
如果我不需要额外的符号或函数,那么这些宏实际上对我有用吗?是否有一个或两个导致gcc生成不同的代码?它们是否可能导致我的代码对标准库函数的调用链接到不同的实现?或者甲骨文是在谈论它的幽冥地区?
编辑:此外,我发现重入是一个单独的线程考虑因素.即使对于单线程程序,非重入也可能是一个问题,因此Oracle建议定义_REENTRANT使gcc多线程感知现在看起来更加可疑.
Oracle 建议是针对 Solaris 编写的,而不是针对 Linux 的。
在 Solaris 上,如果您编译了一个.so没有的文件_REENTRANT并最终由多线程应用程序加载,那么可能会发生非常糟糕的事情(例如 libc 内部的随机数据损坏)。这是因为如果没有定义,默认情况下您最终会得到某些例程的未锁定变体。
我第一次阅读本文档时就是这种情况,大概是 15 年前,-mt在我上次详细阅读本文档后,添加了 sun studio 编译器标志的提及。
现在情况已不再如此 - 无论您是否使用该_REENTRANT标志进行编译,您现在总是会得到相同的例程;它现在只是一个功能宏,而不是行为宏。