本文介绍了fork()和wait()调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对以下代码有疑问.这是在此页面,而不是我的代码.

I have a question about the following code. This is an example found on this page, not my code.

父进程派生2个子进程,每个子进程计数到200,然后退出.我不明白的是,为什么孩子们在分叉后不立即打印他们的消息,而是允许他们的父亲进入等待状态?另外,等待系统调用如何返回最先完成的孩子的pid?

The parent process forks 2 child processes, each of them counting to 200 then exiting. What I don't understand is why aren't the children printing their messages immediately after they are forked and they allow their father to enter waiting status?Also, how is the wait system call returning the pid of the child that finishes first?

pid =等待(& status);

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

#define   MAX_COUNT  200
#define   BUF_SIZE   100

void  ChildProcess(char [], char []);    /* child process prototype  */

void  main(void)
{
     pid_t   pid1, pid2, pid;
     int     status;
     int     i;
     char    buf[BUF_SIZE];

     printf("*** Parent is about to fork process 1 ***\n");
     if ((pid1 = fork()) < 0) {
          printf("Failed to fork process 1\n");
          exit(1);
     }
     else if (pid1 == 0)
          ChildProcess("First", "   ");

     printf("*** Parent is about to fork process 2 ***\n");
     if ((pid2 = fork()) < 0) {
          printf("Failed to fork process 2\n");
          exit(1);
     }
     else if (pid2 == 0)
          ChildProcess("Second", "      ");

     sprintf(buf, "*** Parent enters waiting status .....\n");
     write(1, buf, strlen(buf));
     pid = wait(&status);
     sprintf(buf, "*** Parent detects process %d was done ***\n", pid);
     write(1, buf, strlen(buf));
     pid = wait(&status);
     printf("*** Parent detects process %d is done ***\n", pid);
     printf("*** Parent exits ***\n");
     exit(0);
}

void  ChildProcess(char *number, char *space)
{
     pid_t  pid;
     int    i;
     char   buf[BUF_SIZE];

     pid = getpid();
     sprintf(buf, "%s%s child process starts (pid = %d)\n",
             space, number, pid);
     write(1, buf, strlen(buf));
     for (i = 1; i <= MAX_COUNT; i++) {
          sprintf(buf, "%s%s child's output, value = %d\n", space, number, i);
          write(1, buf, strlen(buf));
     }
     sprintf(buf, "%s%s child (pid = %d) is about to exit\n",
             space, number, pid);
     write(1, buf, strlen(buf));
     exit(0);
}

输出MAX_COUNT 40.

Output for MAX_COUNT 40.

*** Parent is about to fork process 1 ***
*** Parent is about to fork process 2 ***
*** Parent enters waiting status .....
   First child process starts (pid = 3300)
   First child's output, value = 1
      Second child process starts (pid = 3301)
      Second child's output, value = 1
   First child's output, value = 2
      Second child's output, value = 2
      Second child's output, value = 3
   First child's output, value = 3
      Second child's output, value = 4
   First child's output, value = 4
      Second child's output, value = 5
   First child's output, value = 5
      Second child's output, value = 6
   First child's output, value = 6
      Second child's output, value = 7
   First child's output, value = 7
      Second child's output, value = 8
   First child's output, value = 8
      Second child's output, value = 9
   First child's output, value = 9
      Second child's output, value = 10
   First child's output, value = 10
      Second child's output, value = 11
   First child's output, value = 11
      Second child's output, value = 12
   First child's output, value = 12
      Second child's output, value = 13
   First child's output, value = 13
      Second child's output, value = 14
   First child's output, value = 14
      Second child's output, value = 15
   First child's output, value = 15
      Second child's output, value = 16
   First child's output, value = 16
      Second child's output, value = 17
   First child's output, value = 17
      Second child's output, value = 18
   First child's output, value = 18
      Second child's output, value = 19
   First child's output, value = 19
      Second child's output, value = 20
   First child's output, value = 20
      Second child's output, value = 21
   First child's output, value = 21
      Second child's output, value = 22
   First child's output, value = 22
      Second child's output, value = 23
   First child's output, value = 23
      Second child's output, value = 24
   First child's output, value = 24
      Second child's output, value = 25
   First child's output, value = 25
      Second child's output, value = 26
   First child's output, value = 26
      Second child's output, value = 27
   First child's output, value = 27
      Second child's output, value = 28
   First child's output, value = 28
      Second child's output, value = 29
   First child's output, value = 29
      Second child's output, value = 30
   First child's output, value = 30
      Second child's output, value = 31
   First child's output, value = 31
      Second child's output, value = 32
   First child's output, value = 32
      Second child's output, value = 33
   First child's output, value = 33
      Second child's output, value = 34
   First child's output, value = 34
      Second child's output, value = 35
   First child's output, value = 35
      Second child's output, value = 36
   First child's output, value = 36
      Second child's output, value = 37
   First child's output, value = 37
      Second child's output, value = 38
   First child's output, value = 38
      Second child's output, value = 39
   First child's output, value = 39
      Second child's output, value = 40
   First child's output, value = 40
      Second child (pid = 3301) is about to exit
   First child (pid = 3300) is about to exit
*** Parent detects process 3300 was done ***
*** Parent detects process 3301 is done ***
*** Parent exits ***

为什么*** Parent enters waiting status .....行显示在开头而不是孩子开始打印后的某个地方?

Why *** Parent enters waiting status ..... line is displayed at the beginning and not somewhere after the childs start printing?

推荐答案

Fork创建了一个新进程,该进程可以与父进程同时执行(或交错执行).它不会使父进程停止.在fork调用之后,两个进程都是可运行的",并且很有可能两个进程都在运行.如果父进程很幸运,它将是第一个能够输出的进程.一般来说,这是不可预测的.

Fork makes a new process, which can execute simultaneously (or interleaved) with the parent process. It does not make the parent process stop. After the fork call, both processes are "runnable", and it is quite possible that both of them are running. If the parent process is lucky, it will be the first one to be able to output. In general, it is unpredictable.

该代码中存在许多错误,因此我不会将其视为学习如何使用fork()的良好来源.

There are a number of bugs in that code, so I wouldn't treat it as a good source of learning how to use fork().

例如,父进程使用printf编写消息:

For example, the parent process uses printf to write the messages:

*** Parent is about to fork process 1 ***
*** Parent is about to fork process 2 ***

但是,stdout很有可能不是 行缓冲的(例如,它可能被重定向.)在这种情况下,输出将仅复制到内存中输出缓冲区,当缓冲区已满或stdout文件描述符关闭时,将打印到stdout.但是,子级将使用相同的内存输出缓冲区进行分叉,因此父级和子级都将输出*** Parent is about to fork process 1 ***消息,而所有三个进程都将输出*** Parent is about to fork process 2 ***消息.

However, it is quite possible that stdout is not line-buffered (for example, it might be redirected.) In that case, the output will only be copied into the in-memory output buffer, and will be printed to stdout when the buffer fills up or the stdout file descriptor is closed. However, the children will be forked with the same in-memory output buffer, so both the parent and child one will output the *** Parent is about to fork process 1 *** message and all three processes will output the *** Parent is about to fork process 2 *** message.

此外,如果将stdout重定向到未在附加模式下打开的可搜索流,则每个进程的文件描述符1将具有一个关联的文件位置,每个文件位置将独立操作.这可能会导致两个子进程覆盖彼此的输出. (在我的系统上,覆盖大约80%的时间发生.)

Also, if the stdout is redirected to a seekable stream not opened in append mode, then each process's file descriptor 1 will have an associated file position which each will manipulate independently. That may result in the two child processes overwriting each other's output. (On my system, the overwriting happens about 80% of the time.)

这篇关于fork()和wait()调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!