2016-02-22 81 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之間的差異已經有幾個答案。不幸的是,在我的測試中,當我嘗試讀取時,客戶端在讀取之前被父進程終止。