2013-04-18 37 views
1

我與我用來標記句子的服務器進行交互。該服務器通過端口2020在本地啓動。例如,如果我通過下面使用的客戶端端口2020發送Je mange des pâtes .,服務器回答Je_CL mange_V des_P pâtes_N ._.,結果總是隻有一行,如果我的輸入不是空的,結果總是一行。在一個子進程stdin.write中破壞管道

我目前必須通過此服務器標記9 568個文件。前9,483個文件按預期標記。之後,輸入流看起來是關閉/滿/別的,因爲當我嘗試在stdin上寫入時,我得到IOError,特別是Broken Pipe錯誤。

當我跳過前9483個第一個文件時,最後一個標記沒有任何問題,包括導致第一個錯誤的問題。

我的服務器不會產生任何錯誤日誌,指出發生了什麼魚腥味......我處理的東西不正確嗎?一段時間後管道失效是否正常?

log = codecs.open('stanford-tagger.log', 'w', 'utf-8') 
p1 = Popen(["java", 
      "-cp", JAR, 
      "edu.stanford.nlp.tagger.maxent.MaxentTaggerServer", 
      "-client", 
      "-port", "2020"], 
      stdin=PIPE, 
      stdout=PIPE, 
      stderr=log) 

fhi = codecs.open(SUMMARY, 'r', 'utf-8') # a descriptor of the files to tag 

for i, line in enumerate(fhi, 1): 
    if i % 500: 
     print "Tagged " + str(i) + " documents..." 
    tokens = ... # a list of words, can be quite long 
    try: 
     p1.stdin.write(' '.join(tokens).encode('utf-8') + '\n') 
    except IOError: 
     print 'bouh, I failed ;((' 
    result = p1.stdout.readline() 
    # Here I do something with result... 
fhi.close() 
+0

好,代碼看起來有點危險 - 你假設結果始終是一條線。也可以是在遠程主機上運行的服務器,對單個TCP連接中可發送的數據總量實施某些最大限制。也可能是Java客戶端中的問題。 – Aya

+0

@Aya:我已經編輯過,以反映我在本地運行服務器的事實(對於我可以發送的數據總量還有限制嗎?我真的不知道這些事情)。另外,答案總是一條線,我想這個問題不是來自那裏。即使在調試模式下,Java也不會產生任何錯誤,這就是我困惑的原因:(感謝輸入! – m09

+0

它非常依賴於客戶端和服務器代碼,以及客戶端如何將其標準輸入/標準輸出轉換爲TCP /從TCP如果你在本地運行服務器,你可以嘗試從等式中刪除客戶端,並讓Python直接連接到服務器。 – Aya

回答

1

除了我的意見,我可能會建議一些其他的變化......

for i, line in enumerate(fhi, 1): 
    if i % 500: 
     print "Tagged " + str(i) + " documents..." 
    tokens = ... # a list of words, can be quite long 
    try: 
     s = ' '.join(tokens).encode('utf-8') + '\n' 
     assert s.find('\n') == len(s) - 1  # Make sure there's only one CR in s 
     p1.stdin.write(s) 
     p1.stdin.flush()      # Block until we're sure it's been sent 
    except IOError: 
     print 'bouh, I failed ;((' 
    result = p1.stdout.readline() 
    assert result        # Make sure we got something back 
    assert result.find('\n') == len(result) - 1 # Make sure there's only one CR in result 
    # Here I do something with result... 
fhi.close() 

...但考慮也有一個客戶機/服務器,我們一無所知,有一個很多地方可能會出錯。

請問如果轉儲所有查詢到一個單一的文件時,它的工作,然後從類似的命令行運行它...

java .... <input> output 
+0

我會調查你提出的新元素。當我發現新的東西時我會報告:) – m09

+0

@Mog還注意到[Python文檔](http://docs.python.org/2/library/subprocess.html)中的警告:'Use communicate()rather而不是.stdin.write,.stdout.read或.stderr.read,以避免由於任何其他操作系統管道緩衝區填滿和阻塞子進程而造成死鎖。「儘管這需要對每個輸入的」Popen「進行新的調用線。可以這麼說,即使是基於管道的IPC也非常棘手。 :) – Aya

+0

其實我正在經歷這整個事情正是爲了避免在每一步調用Popen(加載一個jvm,x 9 000,它很痛)。但是,它似乎正是我碰到的那種問題:-( – m09

相關問題