微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么从 STDOUT_FILENO 重定向到它的管道中读取会挂起而没有显式 endl 或关闭管道的写端?

如何解决为什么从 STDOUT_FILENO 重定向到它的管道中读取会挂起而没有显式 endl 或关闭管道的写端?

以下代码stdout 重定向到管道的写端,然后我从其读端读取。

// main.cpp
#include <cassert>
#include <iostream>
#include <unistd.h>

int main( int argc,char* argv[] ) {
  int my_pipe[2] = { -1,-1 };
  char buf[100] = { '\0' };
  int stdout_copy;

  assert( -1 != (stdout_copy = dup( STDOUT_FILENO )) );
  assert( 0 == pipe( my_pipe ) );
  assert( -1 != dup2( my_pipe[1],STDOUT_FILENO ) );
  //close( my_pipe[1] );    // (1) Uncommenting this prevents hang.
  //my_pipe[1] = -1;

  std::cout << "hello"
            //<< std::endl  // (2) Uncommenting this also prevents hang.
            ;

  assert( -1 != dup2( stdout_copy,STDOUT_FILENO ) );

  read( my_pipe[0],buf,sizeof buf );
  std::cout << buf;

  close( my_pipe[0] );

  return 0;
}
$ g++ --version && g++ -g ./main.cpp
g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
copyright (C) 2016 Free Software Foundation,Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or fitness FOR A PARTIculaR PURPOSE.

$

玩弄这段代码,我注意到 read 会挂起,除非我 (1) close 我的管道在 dup2 之后 STDOUT_FILENO 写入它,和/或 (2) 显式地将 std::endl 写入 std::cout为什么会这样?

起初,我认为这个问题与 stdout 的刷新有关 - 这可能解释了明确编写 std::endl 的必要性,但是(根据我可能不完整的理解)这并没有t 解释为什么关闭管道的写端会阻止挂起。


更新:我发现这很有趣:当 (1) 和 (2) 都被注释时,std::cout << "hello\n"; 不会阻止挂起;即它不“等同于”std::cout << "hello" << std::endl;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。