3

有人可以向我解释是什么fork() != 0意思吗?据我了解,我认为这意味着如果 fork 不是假的?或者如果 fork 是真的,那么......我不明白 Fork() 如何是真或假,因为它只是将一个进程的副本创建到父子进程中。另外如果一个程序在哪里说if (Fork() == 0),那是什么意思?

 #include "csapp.h"

 int main(void)
 {
     int x = 3;

     if (Fork() != 0)
         printf("x=%d\n", ++x);

     printf("x=%d\n", --x);
     exit(0);
 }
4

6 回答 6

6

fork()如果失败则返回 -1,如果成功,则在父节点中返回分叉子节点的 pid,在子节点中返回 0。所以if (fork() != 0)测试它是否是父进程。

于 2012-09-14T19:03:28.453 回答
3

人叉

返回值

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

假设成功,fork返回两次:一次在父项中,一次在子项中。


好的,我对 OP 造成了伤害:我不知道csapp.h从哪里来,但如果是这个,那么它对你没有任何好处。我猜它是 POSIX 上的一个薄包装器(例如 around fork()),但也许也适用于其他平台?

因为你之前提到fork()Fork(),我认为后者是一个错字,而它实际上是一个库函数。

如果您一直在fork()直接使用,那么期望您查看联机帮助页是合理的。由于您使用的Fork()是某个库提供的功能,因此该库确实应该记录它,但似乎没有。


标准(非csapp)用法是:

pid_t child = fork();
if (child == -1) {
    printf("fork failed - %d - %s\n", errno, strerror(errno));
    exit(-1);
}
if (child) {
    printf("I have a child with pid %d, so I must be the parent!\n", child);
} else {
    printf("I don't have a child ... so I must be the child!\n")
}
exit(0);
于 2012-09-14T19:05:35.737 回答
3

让我们尝试不同的解释......当函数启动时有1个进程,这个进程有一个int x = 3

一旦你点击了这行代码:

if (fork() != 0)

现在,假设 fork() 工作,我们有两个进程。它们都具有相同的执行空间,它们都将运行相同的代码(在一定程度上),但孩子将获得自己的副本x来玩。

fork() 将返回一个 0 给子进程,所以从子进程的角度来看,函数的其余部分是这样的:

printf(("x=%d\n", --x);
exit(0);

另一方面,父进程将从 fork() 命令返回一个有效值,因此它将执行:

printf("x=%d\n", ++x);
printf("x=%d\n", --x);
exit(0);

此时的输出将是任何人的猜测......您无法判断父母或孩子是否会先运行

但是,如果我们假设父级点击++x是下一个操作,那么输出是:

x=4
x=3
x=2

因为父母和孩子都会击中--x. (父母的x在++x之后是4,最后是3。孩子的x是3,最后是2)

于 2012-09-14T19:36:45.857 回答
2

来自 fork() 手册:

Upon successful completion, fork() returns a value of 0 to the child process and returns the process ID of the child process to the parent
     process.  Otherwise, a value of -1 is returned to the parent process, no child process is created, and the global variable errno is set to indi-
     cate the error.

代码执行后,您有两个执行线程。在 if 语句中,您有父进程的线程,在 else 语句中,您有子进程的线程。

if ( fork() ) { 
    printf("I am the parent!\n"); 
} else {
    printf("I am the child\n");
}

编辑

为澄清起见:fork 启动一个进程,该进程具有线程、内存并可能具有其他资源。我尝试(似乎没有成功)通过添加“线程”一词来强调执行流程。但是,决不能说“父进程”与“父进程的线程”中的“线程”有关。

当然,我的答案可以改进,但我认为这里已经有足够好的答案了。

于 2012-09-14T19:04:21.593 回答
1

Fork 将子进程返回 0,将子进程的进程 id 返回给父进程。因此通常代码有 if(fork){ }else 代码。这意味着 if 中的代码将仅在父级中执行。

更好的处理方法是

 pid = fork()
 if(pid){
  // I am parent. Let us do something that only the parent has to do
 }else{
 // I am child. Let us do something only the child has to do
 }
 // This code is common to both

子 pid 可能有助于稍后等待或与父 pid 分离。

于 2012-09-14T19:04:11.180 回答
1

我建议用ifa替换,switch因为有 3 种可能的结果:

#include <sys/types.h>
#include <unistd.h>

pid_t pid;

switch ((pid = fork ())) {
case -1: /* error creating child. */
  break;
case 0:  /* I am the child process. */
  break;
default: /* I am the parent process. */
  break;
}
于 2012-09-14T19:37:10.390 回答