Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C fork()和fork()有什么区别=0和!进程创建中的fork()_C_Unix_Operating System - Fatal编程技术网

C fork()和fork()有什么区别=0和!进程创建中的fork()

C fork()和fork()有什么区别=0和!进程创建中的fork(),c,unix,operating-system,C,Unix,Operating System,目前,我正在做一些基于UNIX操作系统的练习。我使用fork()系统调用创建了一个子进程,代码段如下: if(!fork()) { printf("I am parent process.\n"); } else printf("I am child process.\n"); 这个程序首先执行子进程,然后执行父进程 但是,当我用if(fork()!=0)替换if(!fork())时,会执行父块,然后执行子块。我的问题是,这两种情况下的结果应该是相同的,还是有某种原因?提前谢谢

目前,我正在做一些基于UNIX操作系统的练习。我使用fork()系统调用创建了一个子进程,代码段如下:

if(!fork())
{
   printf("I am parent process.\n");
}
 else
   printf("I am child process.\n");
这个程序首先执行子进程,然后执行父进程

但是,当我用if(fork()!=0)替换
if(!fork())时,会执行父块,然后执行子块。我的问题是,这两种情况下的结果应该是相同的,还是有某种原因?提前谢谢

!fork()
fork()==0
的行为方式相同

条件本身不能成为执行顺序不同的原因。 该进程被复制,这意味着子进程现在正在与父进程竞争资源,包括CPU。由操作系统调度程序决定哪个进程将获得CPU。

!fork()
fork()==0
的行为方式相同

条件本身不能成为执行顺序不同的原因。
该进程被复制,这意味着子进程现在正在与父进程竞争资源,包括CPU。由操作系统调度程序决定哪个进程将获得CPU。

父进程和子进程获得各自的
printf()
语句的顺序未定义。很可能,如果您要重复大量测试,两个版本的结果都会相似,因为对于任何一个版本,都会有父级先打印的时间和父级最后打印的时间。

父级和子级访问各自的
printf()
语句的顺序未定义。很可能,如果您多次重复测试,两个版本的结果都会相似,因为对于任何一个版本,都会有父级先打印的时间和父级最后打印的时间。

  • 没有保证的执行顺序
  • 但是,
    if(!fork())
    if(fork()!=0)
    在逻辑上给出了相反的结果:如果
    fork()
    返回零,则
    !fork()
    为true,而
    fork()=0
    为false
另外,从fork()的手册页:

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

所以正确的检查是

pid_t pid = fork();
if(pid == -1) {
     // ERROR in PARENT
} else if(pid == 0) {
     // CHILD process
} else {
     // PARENT process, and the child has ID pid
}
编辑:正如Wyzard所说,您一定要确保以后也使用pid。(同时,将类型固定为pid而不是int)。

  • 没有保证的执行顺序
  • 但是,
    if(!fork())
    if(fork()!=0)
    在逻辑上给出了相反的结果:如果
    fork()
    返回零,则
    !fork()
    为true,而
    fork()=0
    为false
另外,从fork()的手册页:

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

所以正确的检查是

pid_t pid = fork();
if(pid == -1) {
     // ERROR in PARENT
} else if(pid == 0) {
     // CHILD process
} else {
     // PARENT process, and the child has ID pid
}

编辑:正如Wyzard所说,您一定要确保以后也使用pid。(另外,将类型改为pid\u t而不是int。)

您不应该真正使用这两种类型中的任何一种,因为当子级完成时,在父级也完成之前,它将一直作为僵尸。您应该在变量中捕获子项的pid,并使用它检索子项的退出状态:

pid_t child_pid = fork();
if (child_pid == -1)
{
  // Fork failed, check errno
}
else if (child_pid)
{
  // Do parent stuff...

  int status;
  waitpid(child_pid, &status, 0);
}
else
{
  // Child stuff
}
或者,您应该使用“”将子项与父项分离,这样子项就不会像僵尸一样等待父项检索其退出状态


此外,您不能依赖于在fork之后在父级之前执行的子级。您有两个并发运行的进程,不保证执行的相对顺序。它们可以轮流运行,也可以同时在不同的CPU内核上运行。

您不应该真正使用这两个内核中的任何一个,因为当子内核完成时,在父内核也完成之前,它将一直是一个僵尸。您应该在变量中捕获子项的pid,并使用它检索子项的退出状态:

pid_t child_pid = fork();
if (child_pid == -1)
{
  // Fork failed, check errno
}
else if (child_pid)
{
  // Do parent stuff...

  int status;
  waitpid(child_pid, &status, 0);
}
else
{
  // Child stuff
}
或者,您应该使用“”将子项与父项分离,这样子项就不会像僵尸一样等待父项检索其退出状态


此外,您不能依赖于在fork之后在父级之前执行的子级。您有两个并发运行的进程,不保证执行的相对顺序。它们可以轮流运行,也可以在不同的CPU内核上同时运行。

子进程和父进程的执行顺序由调度程序确定。它确定处理器执行每个进程的时间和持续时间。因此,对于同一个程序代码,输出的顺序可能会有所不同。源代码中的更改导致输出序列的更改,这完全是巧合。 顺便说一句,printf应该正好相反:如果fork()返回0,则它是子进程,而不是父进程


请参阅中的代码示例。这篇文章的德语版本(http://de.wikipedia.org/wiki/Fork_%28Unix%29)包含一个示例输出和一个关于操作顺序的简短讨论。

执行子进程和父进程的顺序由调度程序确定。它确定处理器执行每个进程的时间和持续时间。因此,对于同一个程序代码,输出的顺序可能会有所不同。源代码中的更改导致输出序列的更改,这完全是巧合。 顺便说一句,printf应该正好相反:如果fork()返回0,则它是子进程,而不是父进程

请参阅中的代码示例。这本书的德语版