2016-02-22 64 views
-1

我正在开发一个C++应用程序,它启动一个Python子进程并尝试建立父(C++)和子(Python)之间的通信。特别是我正在编写Python部分,以便与我没有编写并且无法更改的C++应用程序集成。我已经实现了一个套接字解决方案来处理通信,但我还需要支持使用管道的通信。从Python中的stdin读取子进程挂在C++/Python IPC

我的问题是,我可以从Python写入标准输出,并由C++应用程序接收消息。但是,Python子进程无法读取父进程发送的消息。我试图推断的代码,我认为部分是最相关说明问题:当我运行应用程序

C++

void startSubprocess(char* program, char** arguments) 
{ 
    int p_stdout; 
    int p_stdin; 
    int p_stderr; 

    int out[2]; 
    int in[2]; 
    int err[2]; 

    char** arguments; 
    char* program; 

    pipe(out); 
    pipe(in); 
    pipe(err); 
    posix_spawn_file_actions_init(&action); 
    posix_spawn_file_actions_addclose(&action, out[1]); 
    posix_spawn_file_actions_addclose(&action, in[0]); 
    posix_spawn_file_actions_addclose(&action, err[0]); 
    posix_spawn_file_actions_adddup2(&action, out[0], 0); 
    posix_spawn_file_actions_adddup2(&action, in[1], 1); 
    posix_spawn_file_actions_adddup2(&action, err[1], 2); 
    std::vector<char *> vars_c(vars.size() + 1); 

    for (std::size_t i = 0; i != vars.size(); ++i) { 
     vars_c[i] = &vars[i][0]; 
    } 

    vars_c[vars.size()] = NULL; 
    string cwd = __getcwd(); 

    if (directory.size() > 0) 
     chdir(directory.c_str()); 

    if (posix_spawnp(&pid, program, &action, NULL, arguments, vars_c.data())) { 
     cleanup(); 
     pid = 0; 
     if (directory.size() > 0) chdir(cwd.c_str()); 
     return false; 
    } 

    if (directory.size() > 0) chdir(cwd.c_str()); 

    p_stdin = out[1]; 
    p_stdout = in[0]; 
    p_stderr = err[0]; 
} 

void write(const char* buf, int len) 
{ 
    write(p_stdout, buf, len); 
} 

void read(char* buf, int len) 
{ 
    read(p_stdin, buf, len); 
} 

的Python

def writeMsg(msg): 
    sys.stdout.write(msg) 
    sys.stdout.flush() 


def readMsg(): 
    msg = sys.stdin.read() 

父进程(C++)读取由Python子进程发送的消息。之后,Python子进程无法从sys.stdin读取。它会一直等到超时。

当我运行C++应用程序时,我可以看到out = [3,4]和in = [5,6],所以p_stdin = 6和p_stdout = 3。我正在Ubuntu 14.04中测试应用程序。

我一直在尝试其他方法(使用os.fdopen和os.read)但没有成功。欢迎任何解决此问题的建议。谢谢!

编辑

我已经意识到我跳过一些重要的信息了解的问题。主应用程序和Python子进程需要连续地进行通信,读写消息以循环发送和接收,直到终止。该代码看起来是这样的(只是为了描述):

C++

int communicate() 
{ 
    // skip var init etc 

    // launch subprocess 
    startSubprocess(program, arguments); 
    while(1) 
    { 
     // read message sent by subprocess 
     read(msg, len); 
     if(msg == "quit") 
      break; 

     // part of the code that generates msg2 

     // send a message to subproc 
     write(msg2, len2); 
    } 
    return 1;  
} 

的Python

def communicate(): 
    while True: 
     # generate msg to send to C++ 

     writeMsg(msg) 
     msgRcv = readMsg() 
     if msgRcv == 'quit': 
      break 
    return   

回答

0

我已经意识到,sys.stdin.read()挂起,直到EOF在返回消息之前。用

替换msg = sys.stdin.read()
msg = sys.stdin.readline() 

我的应用程序按预期工作。应用程序发送的消息由换行符'\ n'分隔,所以这种方法适用于我。在其他情况下,我认为一次读取一个字符使用

msg += sys.stdin.read(1) 

将避免程序挂起等待EOF。

关于read和readline之间的差异已经有几个答案。不幸的是,在我的测试中,当我尝试读取时,客户端在读取之前被父进程终止。