C 如果(!fork)-这是什么意思?

C 如果(!fork)-这是什么意思?,c,unix,fork,C,Unix,Fork,如果(!fork()),这意味着什么?我对此有点困惑,我不知道我什么时候在家长和孩子的过程中: if(!fork()) { // is it child or parent process? }else{ // is it child or parent process? } 做manfork,你会了解更多。 它实际上返回pid\u t,实际上是int 成功返回时,它为子进程提供,0,为父进程提供正值 实际上是这样的: pid_t pid; pid=fork(); if(pid &l

如果(!fork()),这意味着什么?我对此有点困惑,我不知道我什么时候在家长和孩子的过程中:

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

manfork
,你会了解更多。 它实际上返回
pid\u 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
}
pid\u t pid;
pid=fork();

如果(pid因为
0
可以在条件中使用,就像它是布尔值一样,这与询问相同:

if(fork() == 0) {
文件说:

成功时,在父进程中返回子进程的PID, 并且在子级中返回0。失败时,在子级中返回-1 父进程,不创建子进程,并且错误号设置正确


当编码者只关心“not
0
”或
0
(“true”或“false”)时,直接在条件中使用整数值是一种常见的习惯用法。

调用
fork
在子级中返回0(当然,如果它有效),因此
if
语句的true(第一)部分在那里运行(因为
!0
是true)

false(第二个)部分在父级执行,无论
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;
    }
}
通过该设置,您可以准确地知道发生了什么,而不会丢失任何信息。

来自:

返回值

成功时,在父进程中返回子进程的PID, 并且在子级中返回0。失败时,在子级中返回-1 父进程,不创建子进程,并且错误号设置正确

由于
fork()
将0返回给子级,因此if子句将测试它是否为子级:

if (!fork()) // same as: if (fork() == 0)
{
  // child
}else{
  // parent
}
fork()
的值可以是:

  • 0,这意味着它是一个孩子

  • <0,这是一个错误

  • >0父级,这意味着它是父级

由于
if(!fork())
只是编写
if(fork()=0)
的一种简短方式,因此它的意思是:

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


该代码不会检查fork中的错误!如果已经有太多进程在运行,或者内存不足,fork将失败,并且您的软件可能会以一种非常奇怪的方式运行。

唯一的问题是它没有区分父项和错误。@pmg:如果它也没有记录子项pid,请假定可能家长不关心它发生了什么。所以可能它不关心是否有错误。一个只从一个地方分叉的简单程序可以简单地使用
wait
(而不是
waitpid
)等待它,因此不需要记录pid。
wait
甚至可以通知它
fork
失败(因为没有孩子可供照看)不过,我会考虑这个非常糟糕的设计,因为如果您碰巧使用任何叉码来运行外部程序,那么您可能会错误地收起库代码的子代而不是自己的,并将自己作为僵尸。最好总是保存PID并始终使用<代码> Waistpid < /C>。
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 */
}