stdin和stdout共享任何资源吗?

iPh*_*ian 1 c++ terminal stdin stdout piping

标准输入和标准输出是否独立?

考虑父程序已启动子项,父项的标准输出附加到子项的标准输入,子项的标准输出附加到父项的标准输入.

        stdin       <- stdout 
parent                        child
        stdout ->      stdin
Run Code Online (Sandbox Code Playgroud)

如果孩子(异步地)不断地从其标准输入读取并将数据写入其标准输出,但是父母只是写入孩子的标准输入并且根本没有读取孩子的标准输出:

        stdin|     << stdout 
parent                       child
        stdout ==>==> stdin
Run Code Online (Sandbox Code Playgroud)

最终会出现堵塞吗?标准输入和标准输出是否共享任何类型的缓冲区?特别是通过C++ std::cin(istream)和std::cout(ostream),如果需要回答.标准是否要求他们做或不做这样的事情,还是让它留给实施?

会发生什么?

ric*_*ici 7

您不能将文件描述符从进程"附加"到不同进程的文件描述符.你所做的(如果你的操作系统支持它)是将两个文件描述符分配给"管道"的末尾.管道未在C/C++标准中的任何地方指定(它们由POSIX定义),并且您将找不到任何标准C/C++库函数,它们完全引用它们.

由Unix(和类似Unix)系统实现,管道只不过是操作系统中的某个缓冲区.缓冲区未满时,进程可以将数据写入管道的输入端; 数据只是添加到缓冲区.当缓冲区不为空时,进程可以从缓冲区的输出端读取数据; 数据从缓冲区中删除并传递给读取过程.如果进程尝试写入缓冲区已满的管道或从缓冲区为空的管道读取,则进程"阻塞":即,内核调度程序将其标记为不可运行,并且它将保持该状态,直到管道可以处理它的请求.

问题中描述的场景需要涉及两个管道.一个管道用于允许父项的stdout将数据发送到子项的stdin,另一个管道用于允许子项的stdout将数据发送到父项的stdin.这两根管子完全相互独立.

现在,如果父级停止从其标准输入读取,但子级继续写入其标准输出,则最终管道缓冲区将变满.(它实际上不会花很长时间.管道缓冲区不是很大,而且它们不会增长.)此时,孩子将阻止尝试写入管道.如果孩子没有多线程,那么一旦它阻塞,那就是它.它停止运行,因此它不再从stdin读取.如果孩子停止从其标准输入读取,那么另一个管道将很快变满,父母也会阻止尝试写入标准输出.

因此,不需要共享资源以实现死锁.

这是一个非常着名的过程,它会产生一个孩子,并在阅读孩子的反应时尝试向孩子提供数据.如果读者没有跟上产生的数据,那么很可能会出现死锁.您可以通过搜索"管道缓冲区死锁"来找到有关它的大量信息.以下是一些示例链接,只是随机的:

Raymond Chen,MSDN:http://blogs.msdn.com/b/oldnewthing/archive/2011/07/07/10183884.aspx

就在这里StackOverflow(参考Python但问题是相同的):有人可以解释管道缓冲区死锁吗?

David Glasser,2006年:http://web.mit.edu/6.033/2006/wwwdocs/writing-samples/unix-DavidGlasser.html("这些限制不仅仅是理论上的 - 他们可以在实践中看到这样的事实:以后在Unix中开发的主要进程间通信的主要形式是在管道之上.")