C++ 如何关闭cerr

C++ 如何关闭cerr,c++,posix,C++,Posix,是的,我不能。看起来奇怪的是,ostream并没有关闭,因为istream可以检测到文件的结尾 以下是我的情况:在这个过程中,我通过创建一个管道并将管道输出端复制到fd2上,来捕获Posix fd2上的所有输出及其子对象。然后,线程使用关联的C流读取管道的读取端(并且碰巧通过另一个关联的C流将带有时间戳的每一行写入原始fd2) 当所有的孩子都死了时,我会向cerr写一条关闭消息,然后我需要关闭它,这样将其回送到原始错误文件的线程将关闭管道并终止 线程没有检测到eof(),即使我关闭了stderr

是的,我不能。看起来奇怪的是,ostream并没有关闭,因为istream可以检测到文件的结尾

以下是我的情况:在这个过程中,我通过创建一个管道并将管道输出端复制到fd2上,来捕获Posix fd2上的所有输出及其子对象。然后,线程使用关联的C流读取管道的读取端(并且碰巧通过另一个关联的C流将带有时间戳的每一行写入原始fd2)

当所有的孩子都死了时,我会向cerr写一条关闭消息,然后我需要关闭它,这样将其回送到原始错误文件的线程将关闭管道并终止

线程没有检测到eof(),即使我关闭了stderr和fd2

我用简单的一个复制了我的主程序,用C流代替C++ +流,并且通过关闭STDRR(没有那个简化过程中的子进程),一切都很好。p>


编辑:嗯。。我是否需要在将原始管道fd复制到通道2后关闭它?我没有这样做,所以底层管道仍然连接有一个打开的fd。啊哈。。这就是答案

最好是在资源周围放置一个包装器,然后在它超出范围时让析构函数关闭它。从Bjarne Stoustup

< P>中提出的标准C++流的流与相应的STDIO文件所控制的流相同。也就是说,如果您
fclose(stderr)
您也会关闭用于
std::cerr
的流。。。由于您似乎在使用各种
dup()
函数,因此也可以
close(2)
来关闭此流。

使用
dup2
复制文件描述符时,原始描述符仍然是对底层文件的有效引用。在关闭与特定文件关联的所有文件描述符(使用
close
)之前,不会关闭文件并释放相关资源


如果您正在使用
dup2
将文件描述符复制到一个已知的数字(例如
stderr
的2),您通常希望在成功执行
dup2

后立即调用原始文件描述符上的
close
,我想您应该发送
^D
以结束linux和Windows上的stdio流
^Z
并非所有
ostream
都是基于文件的(例如
std::ostringstream
)因此,在
ostream
上没有类似文件的接口似乎并不奇怪。你是对的,但我们有一个奇怪的现象,cerr无法关闭,即使它被重定向到可以关闭的位置。但是,我正在关闭底层C流和文件描述符,管道另一端的读取使用fdopen'ed C流,我知道它们确实关闭了,因为我检查了一个更简单的情况。当您
dup2
管道时,您是否关闭了原始fd?+1@Charles Bailey。不,我没有。我改变了程序,现在它可以正常工作了。现在请把你的评论作为答案转发给我,这样我就可以勾选:)请阅读这篇文章。我关闭了strr和2。这没有帮助。当您
fclose(stderr)
close(2)
时,文件描述符将明显关闭。您可能想检查其中的任何一个是否失败,但是对于<代码> PONEN()<代码> ED文件,我认为这是不可能的。为确保发送结束消息,您可能需要刷新流,但
std::cerr
通常设置为在所有输出后自动刷新(使用
std::unitbuf
)。也就是说,您的问题不太可能是流的关闭,而是读取端。阅读问题时,您似乎不清楚如何使用文件描述符。您期望终止的线程是否实际写入此流?如果是这样的话,它不会检测到流实际上是关闭的,除非实际上有什么东西试图写入流。@Deitmar:不,它只是读取管道的输入端,其输出端被复制到通道2上,因此它捕获程序和所有子进程的所有错误输出。该程序实际上是一个用于测试0MQ示例的进程管理器,需要运行多个进程(客户端、服务器等)。您是说您正在读取子进程和当前程序写入的文件描述符?你说你把所有的孩子都关了。您是否也关闭了父目录中的文件描述符?只要有一个程序保持文件描述符打开,它就不会被识别为已关闭(毕竟,它不是)。此外,如果你的孩子们终止,他们会自动关闭描述符。我不需要C++中的一个教训,我需要知道如何关闭一个已经重定向到管道的Curr/StDrr/2文件,这样读结束就可以看到EOF。