如果(!fork),它是什么意思?

5

如果是 if(!fork()) 是什么意思?我有点困惑,不知道我是在父进程还是子进程中:

if(!fork())
{
  // is it child or parent process?
}else{
  // is it child or parent process?
}
7个回答

14

fork(2) 手册 来看:

返回值

成功时,子进程的 PID 将在父进程中返回,并在子进程中返回 0。失败时,在父进程中返回 -1,不会创建子进程,并适当设置 errno

由于 fork() 对于子进程返回 0,所以 if 条件语句测试是否为子进程:

if (!fork()) // same as: if (fork() == 0)
{
  // child
}else{
  // parent
}

3
唯一的问题是它无法区分父对象和错误。 - pmg
@pmg:鉴于它也没有记录子进程的pid,父进程可能并不关心它发生了什么。因此,也许它并不在意是否出现错误。 - Steve Jessop
1
一个只从一个地方分支出来的简单程序可以使用wait(而不是waitpid)等待它,因此不需要记录pid。即使fork失败(因为没有子进程等待),wait也可以通知它。但如果你恰好正在使用任何库代码来分叉运行外部程序,这将是非常糟糕的设计,因为你可能会错误地收回库代码的子进程而不是自己的子进程,留下自己的进程成为僵尸进程。最好始终保存pid并始终使用waitpid - R.. GitHub STOP HELPING ICE

4
调用fork函数在子进程中返回0(如果它正常工作),所以if语句的真实(第一个)部分在那里运行(因为!0是真)。假(第二个)部分在父进程中执行,无论fork成功(返回子进程的PID)还是失败(返回-1)。我不太喜欢这种特定方法,因为它没有涵盖所有边缘情况。我更喜欢类似于以下内容的方式:
pid_t pid = fork();
switch (pid) {
    case -1: {
        // I am the parent, there is no child, see errno for detail.
        break;
    }
    case 0: {
        // I am the child.
        break;
    }
    default: {
        // I am the parent, child PID is in pid, eg, for waitpid().
        break;
    }
}

有了这样的设置,您就可以清楚地知道发生了什么,没有信息丢失。


3

因为在条件语句中,0 可以被视为布尔值使用,所以这与以下问题等价:

if(fork() == 0) {

文档中描述:
在父进程中,成功执行时返回子进程的PID;在子进程中,返回0。执行失败时,在父进程中返回-1,不会创建任何子进程,并设置errno为适当值。
通常情况下,如果编写者只关心“不为0”或“为0”(即“true”或“false”),则可以直接在条件语句中使用整数值。

1

执行 man fork 命令,你会更了解它。

实际上,它返回的是 pid_t,也就是 int

如果成功执行,子进程会返回 0,父进程会返回正值。

其实就是这样:

pid_t pid;
pid=fork();

if(pid <0)
{
 printf("fork failed");
 return -1;
}
else if(pid == 0) 
{
  it  is child process
}
else
{
  It is parent process
}

所以当你使用if(!fork())时,它肯定意味着是子进程,因为!0 == 1,即条件为真,它将执行if(!fork())内部的语句。


1

if(!fork())
{
  /*  its child, as child would only be created on success and return 0 which would have been turned into true by ! operator */
}else{
  /* it is parent because either success or failed, fork would have returned nonzero value and ! would have made it false */
}


1

那段代码没有检查fork的错误!当已经有太多进程在运行,或者内存不足时,fork会失败,你的软件可能会表现出非常奇怪的方式。


0

fork() 的返回值可能是:

  • 0,表示它是子进程

  • < 0,表示出现错误

  • > 0,表示它是父进程

由于 if (!fork()) 只是写成 if (fork() == 0) 的简写形式,因此它的意思是:

if(!fork()) {
  // it is a child process
}
else {
  // it is a parent process
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接