为什么父进程的输出被子进程阻止? [英] Why is output of parent process blocked by child process?

查看:90
本文介绍了为什么父进程的输出被子进程阻止?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的代码中,我将进程分叉为父进程和子进程.在子进程中,我将c字符串argv [1]发送到父进程进行打印.然后,我让子进程休眠4秒钟,然后打印这是子进程.正在关闭\ n".

在父进程中,我希望从子进程收到的字符串尽快将其打印到stdout.

这里出现问题.而不是立即在字符串"This is child process.Closing \ n"显示在4秒钟之后的父进程中立即打印argv [1],这是怎么回事:

$ g ++ -std = c ++ 11 printchild.cpp -o printchild

$ ./printchild helloworld

1)4秒过去

2)这是子进程.正在关闭\ n"

3)打印"helloworld"

为什么父进程的输出被子进程阻止?

// printchild.cpp
#include <chrono>
#include <thread>
#include <cstdio>
#include <unistd.h>
#include <cstdlib>

int main(int argc, char * argv[]){
  int pipefd[2];
  pid_t cpid;
  if(argc != 2){
    fprintf(stderr, "Usage: %s <string>\n", argv[0]);
    exit(EXIT_FAILURE);
  }
  if(pipe(pipefd) == -1){
    perror("fork");
    exit(EXIT_FAILURE);
  }
  cpid = fork();
  if(cpid == 0){
    close(pipefd[0]);
    FILE *fpc = fdopen(pipefd[1],"wb");
    fprintf(fpc,"%s",argv[1]);
    fflush(fpc);
    std::this_thread::sleep_for(std::chrono::seconds(4));
    fprintf(stdout,"This is the child process. Closing\n");
    return 0;
  }else if(cpid == -1){
    perror("Error in forking");
    exit(EXIT_FAILURE);
  }else{
    char str[80];
    close(pipefd[1]);
    FILE* fp = fdopen(pipefd[0], "rb");
    fgets(str,80,fp);
    fprintf(stdout,"%s\n",str);
    return 0;
  }
}

解决方案

父进程正在通过fgets()阅读子消息.它将继续读取,直到发生以下三种情况之一为止:

  • 已读取足够的字节来填充缓冲区,而对于字符串终止符则少了一个字节
  • 读取换行符
  • 遇到文件结尾

子级没有发送足够的字节来耗尽缓冲区,也没有发送换行符,因此,父级的fgets()直到子级的管道末端在退出时关闭时才返回.

您可以通过让孩子用换行符终止消息或在写完后立即关闭流来解决此问题.

In my code below, I forked my process into a parent and child process. In the child process, I sent the c string argv[1] to the parent process to be printed. Then I made the child process sleep for 4 seconds before printing "This is the child process. Closing\n".

In the parent process, I want the string from the child process to be printed to stdout as soon as I receive it from the child process.

The problem arises here. Instead of immediately printing argv[1] in the parent process before the string "This is the child process. Closing\n" is printed 4 seconds later, what happens is this:

$ g++ -std=c++11 printchild.cpp -o printchild

$ ./printchild helloworld

1) 4 seconds passes

2) "This is the child process. Closing\n" is printed

3) "helloworld" is printed

Why is the output from the parent process blocked by the child process?

// printchild.cpp
#include <chrono>
#include <thread>
#include <cstdio>
#include <unistd.h>
#include <cstdlib>

int main(int argc, char * argv[]){
  int pipefd[2];
  pid_t cpid;
  if(argc != 2){
    fprintf(stderr, "Usage: %s <string>\n", argv[0]);
    exit(EXIT_FAILURE);
  }
  if(pipe(pipefd) == -1){
    perror("fork");
    exit(EXIT_FAILURE);
  }
  cpid = fork();
  if(cpid == 0){
    close(pipefd[0]);
    FILE *fpc = fdopen(pipefd[1],"wb");
    fprintf(fpc,"%s",argv[1]);
    fflush(fpc);
    std::this_thread::sleep_for(std::chrono::seconds(4));
    fprintf(stdout,"This is the child process. Closing\n");
    return 0;
  }else if(cpid == -1){
    perror("Error in forking");
    exit(EXIT_FAILURE);
  }else{
    char str[80];
    close(pipefd[1]);
    FILE* fp = fdopen(pipefd[0], "rb");
    fgets(str,80,fp);
    fprintf(stdout,"%s\n",str);
    return 0;
  }
}

解决方案

The parent process is reading the child's message via fgets(). It will continue to read until one of three things happens:

  • enough bytes have been read to fill the buffer, less one for a string terminator
  • a newline is read
  • end-of-file is encountered

The child does not send enough bytes to exhaust the buffer, and it does not send a newline, so the parent's fgets() does not return until the child's end of the pipe is closed upon its exit.

You can fix this in the child by having it either terminate the message with a newline or close the stream immediately after writing.

这篇关于为什么父进程的输出被子进程阻止?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆