2015-02-11 64 views
1

我是線程新手,所以我覺得好像我錯過了一個明顯的觀點,但是我找不到與此主題有關的以前的問題。同時閱讀stdin並在python中寫入標準輸出

我想寫一個程序寫入stdin並讀取一個c程序的標準輸出。這是主程序中的代碼。

from subprocess import Popen, PIPE 
from threading import Thread 
from Queue import Queue, Empty 
from os import getcwd 
import time 
import random 

chatter = Queue(maxsize=10) # Queue of strings to be sent to the program 


class Chatter(): 
    def stream_talker(self, identifier, stream): 
     while True: 
      if not chatter.empty(): 
       self.proc.stdin.write(chatter.get(True, 1)) 

    def stream_watcher(self, identifier, stream): 
     while True: 
      for line in stream: 
       print line 

    def main(self): 
     self.proc = Popen(getcwd() + '/main', stdout=PIPE, stdin=PIPE) 
     Thread(target=self.stream_talker, name='stdin-talker', args=('STDIN', self.proc.stdin)).start() 
     Thread(target=self.stream_watcher, name='stdout-listening', args=('STDOUT', self.proc.stdout)).start() 

     while True: 
      chat = raw_input('Enter chatter: ') 
      if len(chat) > 0: 
       chatter.put(chat) 


if __name__ == '__main__': 
    chatt = Chatter() 
    chatt.main() 

這裏是它調用的main.c程序。

#include <stdio.h> 
#include <stdlib.h> 

int main(){ 
    while (1){ 
    int bytes_read; 
    size_t nbytes = 100; 
    char *my_string; 

    my_string = (char *)malloc(nbytes + 1); 
    bytes_read = getline (&my_string, &nbytes, stdin); 

    if (bytes_read == -1) 
    { 
     puts ("ERROR!"); 
    } 
    else{ 
     puts (my_string); 
    } 
    free(my_string); 
    } 

    return 0; 

} 

目前的問題是,雖然它會運行,但stdout永遠不會被打印。

+1

您是否嘗試沖洗緩衝區(兩端)? – 2015-02-11 17:50:16

+0

1.你使用'stream_talker'兩次。你也想運行'stream_watcher'。 2. [你應該強制行緩衝](http://stackoverflow.com/q/20503671/4279)3.它[足以啓動一個線程來同時提供輸入和讀取輸出](http: //stackoverflow.com/q/28291847/4279) – jfs 2015-02-11 18:16:49

+0

@JFSebastian我正在尋找這兩個答案,現在感謝您的鏈接。 – 2015-02-11 18:32:48

回答

3

它看起來像你的主要問題是,你調用兩個stream_talker() s和沒有stream_watcher()

此外,你可能不想忙於等待你的隊列(因爲這違背了使用隊列的全部觀點)。您的代碼儘可能快地輪詢chatter.empty(),直到隊列中有內容爲止。直接使用chatter.get();它會阻塞,直到有可用或直到它超時。

最後,如果您在stream_talker()中寫入stream參數,而不是硬編碼self.proc.stdin,則可能會爲自己節省一些未來的混淆。

+0

還有塊緩衝問題和預讀錯誤 – jfs 2015-02-11 18:21:17

+0

謝謝你給我留下了這個明顯的stream_talker錯誤。然而,省略chatter.empty()會產生空的異常,我把它放在適當的位置以確保不會發生。感謝您指出我不必對其進行硬編碼。 – 2015-02-11 18:27:58

+1

如果隊列仍然爲空,則在超時命中(您已指定超時1秒)後引發異常。如果這不是你想要的,只需調用不帶參數的'.get()'。 – 2015-02-11 18:35:54

相關問題