【问题标题】:Pipes between Python and C++ don't get closedPython 和 C++ 之间的管道不会关闭
【发布时间】:2012-07-03 22:13:07
【问题描述】:

我正在使用子进程在 python 中生成一个进程,并希望使用管道从程序中读取输出。即使明确告诉它关闭,C++ 程序似乎也没有关闭管道。

#include <cstdlib>
#include <ext/stdio_filebuf.h>
#include <iostream>

int main(int argc, char **argv) {
  int fd = atoi(argv[1]);
  __gnu_cxx::stdio_filebuf<char> buffer(fd, std::ios::out);
  std::ostream stream(&buffer);
  stream << "Hello World" << std::endl;
  buffer.close();
  return 0;
}

我用这个 python sn-p 调用这个小程序:

import os                                                                                         
import subprocess                                                                                 

read, write = os.pipe()                                                                           
proc = subprocess.Popen(["./dummy", str(write)])                                                  
data = os.fdopen(read, "r").read()                                                                
print data                                                                                        

read() 方法没有返回,因为 fd 没有关闭。在python中打开和关闭write fd解决了这个问题。但这对我来说似乎是一个黑客行为。有没有办法在我的 C++ 进程中关闭 fd?

非常感谢!

【问题讨论】:

    标签: c++ python pipe


    【解决方案1】:

    在 Linux(实际上是所有 POSIX 操作系统)上生成子进程通常通过 forkexec 完成。在fork 之后,两个进程都打开了文件。 C++ 进程将其关闭,但文件保持打开状态,直到父进程也关闭 fd。这对于使用fork 的代码来说是正常的,通常由fork 周围的包装器处理。阅读man 页面以获取pipe。不过,我猜 python 无法知道哪些文件正在传输给子进程,因此不知道在父进程和子进程中要关闭什么。

    【讨论】:

    • 有趣。意思是你在构造Popen对象之后关闭了文件描述符?
    • 另请参阅 Python 文档中的示例:docs.python.org/library/…。 “如果 p2 在 p1 之前退出,则 p1.stdout.close() 在启动 p2 后调用很重要,以便 p1 接收 SIGPIPE。”这意味着,是的,请关闭 Python 进程中的句柄。
    • 感谢您澄清这一点!
    【解决方案2】:

    POSIX 文件描述符是进程本地的。 Python 工具中的文件描述符write 在 C++ 进程中无效。

    也许最简单的方法是让 C++ 进程将其输出写入stdout(如cout &lt;&lt;),Python 使用stdout=PIPE 调用Popen 并读取proc.stdout(或改用proc.communicate()使用fdopen。这也应该在Windows中工作。

    如需将文件描述符作为命令行参数传递,请参阅Ben Voigt's answer

    【讨论】:

    • 条件是什么我不记得了,但是可以继承文件描述符。
    猜你喜欢
    • 2020-11-03
    • 1970-01-01
    • 1970-01-01
    • 2010-09-11
    • 2016-08-27
    • 1970-01-01
    • 2014-08-13
    • 2018-02-08
    • 1970-01-01
    相关资源
    最近更新 更多