为什么fork()函数返回的主进程的PID值比原来大1?

问题描述 投票:0回答:2

我尝试编写我的“getpid”克隆,因为我有一个学校项目,而 getpid 是被禁止的功能。所以,我写了这段代码:

pid_t   mini_getpid(void)
{
    pid_t   id;

    id = fork();
    if (id == 0)
        exit(0);
    else
    {
        wait(0);
        return (id - 1);
    }
}

我尝试使用 fork 函数获取主进程的 pid。但有一个问题。当我比较我的返回值和真实的 getpid() 函数时,我的函数总是返回大 1 的值。例如,如果 getpid() 的返回值是 1000,那么由于 fork 函数,我的函数会返回 1001。 fork 函数做错了什么?为什么它返回的 PID 值比应有的值大 1?

c process pid
2个回答
0
投票

Fork 返回子进程的 PID,到目前为止,它在您的机器和环境上一直比父进程高 1,这纯粹是运气。这并不是一个保证;而是一个保证。内核可以为子进程分配任何有效的、未使用的 PID。

如果您确实需要 getpid 而不调用 getpid C 函数,您始终可以调用原始系统调用

#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
int main(void) {
  pid_t pid = syscall(SYS_getpid);
  pid_t pid2 = getpid(); // for comparison
  printf("%d %d\n", pid, pid2);
  return 0;
}

如果您的任务精神是不使用该系统调用,那么您将不得不探索提供您所需信息的其他辅助渠道。最好的方法显然取决于你在任务中可以做什么和不可以做什么。

另一种可能(但效率低下)的方法是在子进程到父进程之间建立某种通信通道(例如共享内存、管道等),并在子进程中进行

getppid
调用。


0
投票

您正在对父 pid 和子 pid 之间的关系做出不应该做出的假设。子 pid 可以是任何东西,所以

child_pid - 1
不是获取父 pid 的正确方法。

如果

getpid()
是唯一被禁止的函数,您可以在子进程中使用
getppid()
(获取父进程 pid),然后通过
pipe
将其发送回父进程。

这是一个例子。添加错误检查留作练习。

#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

enum { P_RD, P_WR };

pid_t mini_getpid(void) {
    int fds[2];
    pipe(fds);                      // create a pipe

    pid_t id = fork();
    if (id == 0) {
        close(fds[P_RD]);           // close the reading end of the pipe
        pid_t parent = getppid();   // get parent pid
        write(fds[P_WR], &parent, sizeof parent); // send it to the parent
        close(fds[P_WR]);           // close the writing end
        exit(0);
    }
    // in parent process
    close(fds[P_WR]);                 // close the writing end       
    read(fds[P_RD], &id, sizeof id);  // read the pid written by the child
    close(fds[P_RD]);                 // close the reading end

    return id;
}
© www.soinside.com 2019 - 2024. All rights reserved.