3

我试过实现一个操作系统程序。这是代码:

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

int main()
{
    pid_t pid, pid1;

    pid = fork();

    if(pid<0)
    {
            fprintf(stderr,"Fork Failed");
            return 1;
    }

    else if(pid == 0) /* child process */
    {
            pid1 = getpid();
            printf("child: pid = %d\n",pid);
            printf("child: pid1 = %d\n",pid1);

    }

    else   /* parent process */
    {
            pid1 = getpid();
            printf("parent: pid = %d\n",pid);
            printf("parent: pid1 = %d\n",pid1);

    }

    return 0;
}

及其o/p:

parent: pid = 1836
parent: pid1 = 1835
child: pid = 0
child: pid1 = 1836

有人可以解释一下它是如何工作的,即代码中编写的 // 语句的if执行顺序else-ifelse我认为一旦else if条件变为真else,则不执行部分,但是在这里它已经执行了父进程部分,即else部分,然后是子部分.....怎么会?

4

4 回答 4

5

您应该阅读fork()。一旦你点击了一个fork()语句,第二个进程就会启动,它拥有父进程所有内容的副本,但它可以运行单独的执行,并且它看到的返回与父进程看到的fork不同。

 int main()
 {
   pid_t pid, pid1;
                   <--- up to here you have one process running
   pid = fork();   <--- when this returns you have two processes:
                          parent has pid = child's pid               child has pid = 0


   if(pid<0)       <--- child and parent both check this, it's not true so they move on
   {
     ....
   }
   else if(pid == 0)<--- this is true for the child, not the parent
   {
     ....           <--- child will now execute this code
   }
   else             <-- nothing else was true for the parent so it sees this
     ....           <-- and executes this code

所以是的,你是对的,一旦你点击if, 或 the else ifelse你就不会在单个进程的 execution 中进入代码的另一个分支。您看到else if和 是else因为您有两个进程正在运行。

请注意pid1's 的不同之处,因为getpid()返回的是哪个进程正在运行该代码,并且您可以看到您有两个不同的进程,一个选择else if另一个选择else.

于 2012-11-14T12:32:27.030 回答
3

man fork

fork 实际上返回zero子进程 id 和non-zero父进程意味着子进程的实际进程 id 返回给父进程

之后else if(pid ==0 ) {...}是子进程

并且else {...}是父进程。

fork 的基本含义是创建新的进程。

如果 main 调用一个fork(),那么只有一个子被创建,它有自己的地址空间。就在 fork 调用下方,父进程和子进程的所有语句都是相同的。

使用fork创建进程意味着这两个是独立的进程parentchild默认情况下它们之间不共享任何数据

但是在您的情况下,在 fork 调用之后这两个是独立的,因此这两个进程的执行顺序是未指定的。你可能会得到这些东西:

1. parent executed and program terminates
parent: pid = 1235
parent: pid1 = 1234


2. child executed then parent and then program terminates :
child : pid = 0
child :pid1 = 1235
parent : pid = 1235
parent :pid1 = 1234

如果你想确保孩子必须先执行,然后父母应该退出。在父代码中放一行wait(NULL);作为第一条语句,else{..} 这意味着父代码将等到子代码终止。

于 2012-11-14T12:20:56.310 回答
3

fork() 创建一个新进程,该进程独立于原始进程执行。

您的新子进程运行该else if部分。

您现有的父进程运行该else部件。

您的子进程和父进程之间的执行顺序不是确定性的,它们现在是不同的进程,操作系统将安排它们运行,但内核感觉如何。父进程或子进程首先运行其代码可能或多或少是随机的。

你甚至可以让孩子和父母的 printfs 交错。

于 2012-11-14T12:28:12.173 回答
2

有两个不同的进程正在运行您的程序。调用后fork,以下指令有两次执行,它们的值不同pid。所以else ifelse部分都被执行,每个都由两个进程之一执行。

于 2012-11-14T12:20:28.433 回答