C语言 为什么fork()函数返回的主进程的PID值大于1?

zf2sa74q  于 2023-08-03  发布在  其他
关注(0)|答案(2)|浏览(153)

我试着写我的“getpid”克隆,因为我有一个学校项目,getpid是禁止的函数。所以,我写了这段代码:

  1. pid_t mini_getpid(void)
  2. {
  3. pid_t id;
  4. id = fork();
  5. if (id == 0)
  6. exit(0);
  7. else
  8. {
  9. wait(0);
  10. return (id - 1);
  11. }
  12. }

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

laik7k3q

laik7k3q1#

分叉returns the child's PID,到目前为止,它在您的机器和环境中一直比父代高1,这纯粹是运气。这不是保证内核可以为孩子分配任何有效的、未使用的PID。
如果你真的需要在不调用getpid C函数的情况下获取pid,你可以调用原始系统调用:

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

字符串
如果你的任务的精神是甚至不使用系统调用,你将不得不探索其他渠道,提供你需要的信息。最好的方法显然取决于你在任务中允许做什么和不允许做什么。
另一种可能的(但效率不高的)方法是在子进程和父进程之间建立某种通信通道(例如:共享内存、管道等)和子进程中的getppid调用。

yquaqz18

yquaqz182#

你正在对父pid和子pid之间的关系做出不应该做出的假设。子pid可以是任何东西,所以child_pid - 1不是获取父pid的正确方法。
如果getpid()是唯一被禁止的函数,你可以在子进程中使用getppid()(以获取父进程的pid),然后通过pipe将其发送回父进程。
举个例子添加错误检查将作为练习。

  1. #include <stdlib.h>
  2. #include <sys/wait.h>
  3. #include <unistd.h>
  4. enum { P_RD, P_WR };
  5. pid_t mini_getpid(void) {
  6. int fds[2];
  7. pipe(fds); // create a pipe
  8. pid_t id = fork();
  9. if (id == 0) {
  10. close(fds[P_RD]); // close the reading end of the pipe
  11. pid_t parent = getppid(); // get parent pid
  12. write(fds[P_WR], &parent, sizeof parent); // send pid to parent
  13. close(fds[P_WR]); // close the writing end
  14. exit(0);
  15. }
  16. // in parent process
  17. int mypid;
  18. close(fds[P_WR]); // close the writing end
  19. read(fds[P_RD], &mypid, sizeof mypid); // read the pid from the pipe
  20. close(fds[P_RD]); // close the reading end
  21. int wstatus;
  22. waitpid(id, &wstatus, 0); // wait for child to exit
  23. return mypid;
  24. }

字符串

展开查看全部

相关问题