2015-08-14 48 views
2

我正试图集成一个小型的Win32 C++程序,它从stdin读取并将解码结果(~128千字节)写入输出流。我应该总是明确地关闭stdout吗?

我读整个输入到缓冲用

while (std::cin.get(c)) { } 

我写整个输出到标准输出后。

当我从命令行运行应用程序时,一切工作正常,例如test.exe <input.bin> output.bin,但是这个小应用程序应该从Python运行。

我想到了Python subprocess.communicate应该被使用,文档说:

与互动的过程:将数据发送至标准输入。从stdout和 stderr中读取数据,直到达到文件结束。等待进程终止。

因此communicate()将等待我的应用程序完成前等待文件结束 - 应用程序退出时是否应该发生EOF?或者我应该明确做fclose(stderr)和fclose(stdout)?

+4

您不应该明确地释放您未明确获取的任何资源,除非您有特定的文档说明否则。如果不坚持这一点,则难以解决问题。 – mah

+0

现在我明白了这一点 - 子进程获取自己的句柄/描述符,用于至少在子进程终止时关闭的管道的另一端。 –

+1

无关联:模拟'test.exe < input.bin > output.bin' shell命令,可以使用'subprocess.check_call('test',stdin = open('input.bin'),stdout = open('stdout.bin', 'w'))'即你不需要'.communicate()'。 – jfs

回答

8

不要关闭标准输出

在一般情况下,这其实是错误的,因为它可以注册atexit()一个函数,它试图写入标准输出,并且如果stdout被关闭,这将打破。

当进程终止时,操作系统自动关闭所有句柄。这包括标准输出,因此您不负责手动关闭它。

(技术上,C++运行时将normally尝试刷新并关闭所有的C++流之前的OS甚至有机会参与,但操作系统绝对必须关闭任何手柄,其运行时,为whateverreason,失误。)

在特殊情况下,关闭标准流(例如,守护进程时)可能很有用,但应该非常小心。将空设备重定向到空设备通常是一个好主意(Unix上的/dev/null,Windows上的nul),以便期望与这些流进行交互的代码仍然可以工作。在Unix上,这是通过freopen(3)完成的; Windows有an equivalent function,但它是POSIX API的一部分,可能无法与标准Windows I/O配合使用。

+0

我会稍微修改一下 - 如果你有特定的原因这样做,关闭标准输出可能是可以接受的,即你需要在没有实际退出的情况下发出数据结束的信号。当然,你必须小心确保程序在这样做之后不会使用stdout。 –

+0

@HarryJohnston:在某些特殊情况下这可能是合理的,但您需要仔细评估您可能使用的任何库或其他代码。例如,在某些系统上,当某个进程通过信号死亡(“Terminated”,“Killed”,“Segmentation Fault”等)时,您可能会得到输出,而且我不确定是否需要功能stdout/stderr,或者如果没有标准输出则表现如何。 – Kevin

+0

你可以关闭然后用/ dev/null重新打开3个std句柄,这样0,1,2路由为null,就像我们如何守护进程一样。 –

相关问题