关于简单的python subprocess.Popen任务的无尽问题

1 投票
2 回答
626 浏览
提问于 2025-04-15 21:57

我想让Python发送大约50万个整数,这些整数的范围是0到255,给一个用C++写的可执行文件。这个可执行文件会返回几千个整数,每个整数占一行。看起来用subprocess来实现这个应该很简单,但我遇到了无尽的麻烦。目前我在测试的代码是:

// main()
u32 num;
std::cin >> num;

u8* data = new u8[num];
for (u32 i = 0; i < num; ++i)
    std::cin >> data[i];

// test output / spit it back out
for (u32 i = 0; i < num; ++i)
    std::cout << data[i] << std::endl;

return 0;

我在Python中构建了一个字符串数组("data"),每个字符串像这样:"255\n",然后使用:

output = proc.communicate("".join(data))[0]

...但这不管用(提示说标准输入已关闭,可能一次发送太多数据了)。使用proc.stdin和proc.stdout也没有成功。这本应该非常简单,但我一直收到异常,或者根本没有返回数据给我。我的Popen现在是:

proc = Popen('aux/test_cpp_program', stdin=PIPE, stdout=PIPE, bufsize=1)

在我快抓狂之前,请给我点建议。;)

2 个回答

1

这个对我来说完全没问题:

#include <iostream>

int main()
{
    int num;
    std::cin >> num;

    char* data = new char[num];
    for (int i = 0; i < num; ++i)
        std::cin >> data[i];

    // test output / spit it back out
    for (int i = 0; i < num; ++i)
        std::cout << data[i] << std::endl;

    return 0;
}

python:

In [9]: from subprocess import Popen, PIPE
In [10]: a = Popen('./a.out', stdin=PIPE, stdout=PIPE)
In [11]: a.stdin.write("2\nab")
In [12]: a.stdout.read()
Out[12]: 'a\nb\n'

注意,我在要写入的字节数之间加了一个分隔符(\n),这样做是最安全的。如果你不想让你的C++中的cin在发送像3,1,2,3这样的内容时出错,因为这些内容会连在一起变成3123,这样就会期待有那么多个参数。

0

在C++中,当你从cin读取一个charunsigned char时,它实际上是从stdin读取一个字节。不过,你可能希望它能读取一个从0到255的十进制数字。如果你读取一个int类型的数据,它就能正确读取这个数字:

unsigned int n;
std::cin >> n;
data[i] = static_cast<u8>(n);

另外,你也可以让Python代码把值写成字节序列,而不是数字,这可以通过使用chr函数来实现。

撰写回答