Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux进程/线程是否可以在不通过do_exit()的情况下终止?_Linux_Multithreading_Linux Kernel_Exit_Printk - Fatal编程技术网

Linux进程/线程是否可以在不通过do_exit()的情况下终止?

Linux进程/线程是否可以在不通过do_exit()的情况下终止?,linux,multithreading,linux-kernel,exit,printk,Linux,Multithreading,Linux Kernel,Exit,Printk,为了验证我想使用的第三方二进制分布式软件的行为,我正在实现一个内核模块,其目标是跟踪该软件生成和终止的每个子级 目标二进制文件是Golang生成的,并且是多线程的。 我编写的内核模块在内核函数\u do\u fork()和do\u exit()上安装钩子,以跟踪此二进制文件生成和终止的每个进程/线程 LKM或多或少是有效的 然而,在某些情况下,我有一个无法解释的场景。 进程/线程似乎可以在不经过do\u exit()的情况下终止 我通过放置printk()收集的证据显示了进程的创建,但并不表示进

为了验证我想使用的第三方二进制分布式软件的行为,我正在实现一个内核模块,其目标是跟踪该软件生成和终止的每个子级

目标二进制文件是Golang生成的,并且是多线程的。 我编写的内核模块在内核函数\u do\u fork()do\u exit()上安装钩子,以跟踪此二进制文件生成和终止的每个进程/线程

LKM或多或少是有效的

然而,在某些情况下,我有一个无法解释的场景。 进程/线程似乎可以在不经过do\u exit()的情况下终止

我通过放置printk()收集的证据显示了进程的创建,但并不表示进程的终止

我知道printk()可能会很慢,而且我也知道在这种情况下消息可能会丢失

为了防止由于控制台速度慢而导致的消息丢失(对于这个特定的应用程序,使用了串行tty 115200),我尝试实现一个更快的控制台,并使用netconsole收集消息

所述设置似乎确认了一个进程可以在不通过do\u exit()函数的情况下终止

但是因为我不确定我的消息不会在printk()基础设施上丢失,我决定重复相同的测试,但将printk()替换为ftrace_printk(),这应该是printk()的更精简的替代方案

仍然是相同的结果,有时我会看到进程没有通过do_exit(),如果要验证PID当前是否正在运行,我必须面对它没有运行的事实

还要注意,我将钩子放在do_exit()内核函数中作为第一条指令,以确保函数流不会在被调用函数中终止

我的问题是:

Linux进程是否可以在其流未通过do_exit()函数的情况下终止

如果是这样的话,有人能给我一个关于这个场景的提示吗

Linux进程是否可以在其流不通过do_exit()函数的情况下终止

可能不会,但您应该研究的源代码以确定。继续问。内核线程和/或相关事物(或者可能是
modprobe
或较旧的
hotplug
)是可能的例外。当pid 1的
/sbin/init
终止时(这不应该发生),奇怪的事情就会发生

LKM或多或少是有效的

这意味着什么?内核模块如何工作


在现实生活中,有时确实会发生Linux内核损坏或崩溃的情况(如果您的LKM没有经过Linux内核社区的同行审查,它可能会发生在LKM上)。在这种情况下,没有更多的概念,因为它们是由一个活的Linux内核提供的抽象

另见

还可以查看libc的源代码,例如

当然,请参见和

以及验证PID当前是否正在运行

这可以通过用户登陆
/proc/
,或使用0信号(也可能是…)来实现


另外,我仍然不明白为什么需要编写内核模块或更改内核代码。我的直觉是尽可能避免这样做。

经过长时间的调试,我终于能够回答我自己的问题了

这还不是全部;我也能解释为什么我看到了我在场景中描述的奇怪行为

让我们从头开始:监视大量多线程应用程序。我观察到很少有PID突然停止而没有观察到它通过Linux内核do_exit()函数的流程的情况

因为这是我最初的问题:

Linux进程是否可以在不通过do_exit()函数的情况下终止

至于我目前的知识,我现在认为是相当广泛的,一个Linux进程不能结束它的执行而不通过<强> doJeXIT()/<强>函数。< /P> 但这个答案与我的观察结果形成了对比,导致我提出这个问题的问题仍然存在

这里有人说我观察到的奇怪行为是因为我的观察有点错误,暗示我的方法不准确,至于我的结论

我的观察是正确的,我观察的过程没有通过do_exit(),而是终止了

为了解释这一现象,我想提出另一个我认为互联网搜索者可能会觉得有用的问题:

两个进程是否可以共享相同的PID

如果你一个月前问我这个问题,我肯定会回答这个问题:“绝对不会,两个进程不能共享同一个PID。” 不过,Linux更为复杂

在Linux系统中,两个不同的进程可以共享同一个PID

令人惊讶的是,这种行为不会伤害任何人;当这种情况发生时,这两个进程中的一个就是僵尸

如果线程引线在其子线程之前终止,则预期的行为是用引线的PID替换子线程的PID之一。这也意味着孩子的PID突然停止存在。

这就是我所看到的;我正在监视的PID没有通过do_exit(),因为当相应的线程终止时,它不再具有启动时的PID,而是具有其前导的PID

对于那些非常了解Linux内核机制的人来说,这并不奇怪;这种行为是有意的,自2.6.17以来没有改变。 咖喱