gpt4 book ai didi

Java Native Interface 偷偷摸摸的 fork 行为

转载 作者:行者123 更新时间:2023-12-04 00:51:32 26 4
gpt4 key购买 nike

经过非常长时间的搜索和相关错误,我发现了这种奇怪的行为:

如果在 Linux 上我运行一个 JNI 方法来执行 select:

JNIEXPORT void JNICALL Java_SelectJNI_select(JNIEnv *env, jobject thisObj) {
// Print the curerent PID
fprintf(stderr, "PID: %d\n", getpid());

// Wait for 30 seconds
struct timeval *timeout = (struct timeval *) calloc(1, sizeof(struct timeval));
timeout->tv_sec = 30;
timeout->tv_usec = 0;
select(0, NULL, NULL, NULL, timeout);

return;
}

然后我用 strace 运行可执行文件,select 不是用我打印的 PID 执行的,而是用 child 的 PID 执行的,原始对象实际上在等待互斥锁(这如果我在普通的小型 C 程序中执行相同的调用,则不会发生。

strace -f -o strace_output.txt java SelectJNI 打印:

PID: 46811 

然后 grep select\( strace_output.txt 将返回:

46812 select(0, NULL, NULL, NULL, {tv_sec=30, tv_usec=0} <unfinished ...>

我的猜测是 JNI 正在 fork ,以某种方式用它自己的包装版本替换原始选择,可能是为了保持响应。

我有很多问题,但我更关心的是:

  1. 我的假设正确吗? JNI 取代了我脚下的功能?
  2. 是否在某处记录了此行为?
  3. 调用实际选择的过程似乎总是第一个 child 的过程。我可以依靠它吗?如果不是,我如何找出 select 实际运行的位置?

最佳答案

JVM 确实可以 fork ,但这样做是为了创建新的 JVM 线程,而不是整个进程。虽然 46811 是 PID,但实际运行您的代码的线程具有 TID 46812(这是 strace 打印的内容),同时仍在 PID 46811 下运行。替换 getpid在示例中使用 gettid 应该会导致一致的输出。

关于Java Native Interface 偷偷摸摸的 fork 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66122018/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com