Проблемы EOF в конвейере с stdio и C ++ / Python - PullRequest
0 голосов
/ 14 марта 2010

У меня возникли некоторые проблемы с EOF и stdio в конвейере связи между процессом Python и программой C ++.Я понятия не имею, что я делаю не так.Когда я вижу EOF в своей программе, я очищаю стандартный ввод, и в следующем раунде я пытаюсь читать в новой строке.Проблема в том, что по какой-то причине функция getline немедленно (начиная со второго запуска всегда, первый работает точно так же, как и предполагалось) возвращает EOF вместо ожидания нового ввода от процесса python ... Есть идеи?

хорошо Вот код:

#include <string>
#include <iostream>
#include <iomanip>
#include <limits>

using namespace std;

int main(int argc, char **argv) {
    for (;;) {
        string buf;
        if (getline(cin,buf)) {
            if (buf=="q") break;
            /*****///do some stuff with input //my actual filter program
            cout<<buf;
            /*****/
        } else {
            if ((cin.rdstate() & istream::eofbit)!=0)cout<<"eofbit"<<endl;
            if ((cin.rdstate() & istream::failbit)!=0)cout<<"failbit"<<endl;
            if ((cin.rdstate() & istream::badbit)!=0)cout<<"badbit"<<endl;
            if ((cin.rdstate() & istream::goodbit)!=0)cout<<"goodbit"<<endl;
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max());

            //break;//I am not using break, because I
                    //want more input when the parent
                    //process puts data into stdin;
        }
    }

    return 0;
}

и в Python:

from subprocess import Popen, PIPE
import os
from time import sleep

proc=Popen(os.getcwd()+"/Pipingtest",stdout=PIPE,stdin=PIPE,stderr=PIPE);

while(1):
  sleep(0.5)

  print proc.communicate("1 1 1")
  print "running"

1 Ответ

1 голос
/ 14 марта 2010

communicate в питоне - это функция одного выстрела. Он отправляет заданные входные данные процессу, закрывает входной поток и считывает выходные потоки, ожидая завершения процесса.

Невозможно «перезапустить» канал с тем же процессом после «связи».

И наоборот, на другой стороне канала, когда вы читаете EOF, больше нет данных для чтения. Любая попытка чтения немедленно вернет EOF; питон закрыл трубу.

Если вы хотите продолжить связь с тем же каналом, вам нужно использовать элементы stdin и stdout подпроцесса, а не communicate (но будьте осторожны с возможными взаимоблокировками) и использовать что-то кроме конец потока, сигнализирующий, что сторона C ++ должна выполнить еще один «пакет» обработки.

...