首页 > 解决方案 > pid存储在哪里?

问题描述

我在作业中有以下问题:
在每一内,一个进程调用以下函数:

#include <string>
using namespace std;
string create_file_name(time_t timestamp) {
 pid_t pid = getpid();
 string s = “results-” + to_string(pid) + to_string(timestamp);
 return s;
}

问题是内核将进程PID存储在哪里?
有5个不同
的答案:用户栈\内核栈\堆\PCB\runqueue

现在一般来说,我知道 PID 存储在 PCB 中,但在这种情况下,它是否也应该存储在用户的堆栈中?(因为它是一个局部变量)。
这个问题似乎只有一个答案,所以我很困惑。

标签: c++processpid

解决方案


如手册页所述:

从 glibc 2.3.4 版到 2.24 版(包括 2.24 版),用于 getpid() 的 glibc 包装函数缓存了 PID,目的是在进程重复调用 getpid() 时避免额外的系统调用。通常这种缓存是不可见的,但它的正确操作依赖于对 fork(2)、vfork(2) 和 clone(2) 的包装器函数的支持:如果应用程序通过使用 syscall(2) 绕过了这些系统调用的 glibc 包装器),然后在子进程中调用 getpid() 将返回错误的值(准确地说:它将返回父进程的 PID)。此外,即使通过 glibc 包装函数调用 clone(2),getpid() 也可能返回错误值。(有关此类情况的讨论,请参见 clone(2) 中的 BUGS。)此外,

由于上述问题,从 glibc 版本 2.25 开始,PID 缓存被删除:对 getpid() 的调用总是调用实际的系统调用,而不是返回缓存值。

在 Alpha 上,提供了一个 getxpid() 系统调用,而不是一对 getpid() 和 getppid() 系统调用,它返回一对 PID 和父 PID。glibc getpid() 和 getppid() 包装函数透明地处理这个问题。有关寄存器映射的详细信息,请参见 syscall(2)。

这取决于glibc你使用的。实际上在某些版本中glibc保留了 pid 的缓存,而在某些版本中,它会重复调用 syscall 来获取进程的 pid,如果您想知道系统调用是如何工作的,建议您查看内核代码。

您可以在此链接中找到该getpid()功能。(您可以更改内核版本并浏览所有源代码以重建系统调用的工作方式。getpid()


推荐阅读