2011-07-20 13 views
1

私はPythonプログラムからシェルを実行しようとしています。 私は、ユーザーからの入力が受け入れられ、シェル経由で実行されるmltithreadedアプローチを使用しました。Popen.stdinでマルチスレッドの問題が発生しました。

プログラムの実行がstdinを超えて行われないことを除いて、すべてが正しいように見えます。

Popen.stdinの使用方法に問題があるかどうかはわかりません。

ここで間違っていると助けてください。

from subprocess import Popen,PIPE 
import shlex 
import threading 
from Queue import Queue 


class MyThread(threading.Thread): 
    def __init__(self,func,args): 
     threading.Thread.__init__(self) 
     self.func=func 
     self.args=args 

    def run(self): 
     apply(self.func,self.args) 



def bash(command,output): 
    commandList=shlex.split('python test.py') 
    process=Popen(commandList,stdout=PIPE,stdin=PIPE,stderr=PIPE,shell=True) 
    print process.stdout.readlines() 
    while (process.pole()==None): 
     #commandList=shlex.split(command.get(1)) 
     print 'bash' 
     process.stdin.write(command.get(1)) 
     process.stdin.flush() 
     output.put(process.stdout.readlines(),1) 
     process.stdout.flush() 



def communicate(command,output): 
    while True: 
     command.put(raw_input('enter command>')) 
     print 'communicate' 
     print output.get(1) 



funcs=[bash,communicate] 
nfuncs=len(funcs)  

def main(): 

    command=Queue(1) 
    output=Queue(1) 
    threads=[] 

    for i in range(nfuncs): 
     t=MyThread(funcs[i],(command,output)) 
     threads.append(t) 

    for i in range(nfuncs): 
     threads[i].start() 

    for i in range(nfuncs): 
     threads[i].join() 

    print 'successful'  

if __name__=='__main__': 
    main() 

次の出力を示しました。

[email protected]:~/TerminalChatBot/test$ python threadTerminal.py 
enter command>ls 
communicate 

これ以降は実行されません。私もCtrl + Cを使用してPythonスクリプトを停止することはできません。それはちょうどハングアップします。

注:このコードをより大きなモジュールと統合する必要があるので、スレッド通信がそこにある必要があります。

+0

を、私はあなたが[ 'multiprocessing'](HTTPを使用することをお勧め.python.org/library/multiprocessing.html) 'サブプロセス' + 'threading' – mac

+0

なぜマルチスレッドではなく、Pythonのマルチプロセスアプローチを使用していますか? – Cinquo

答えて

0

マイナーなもの:

それはprocess.poll()ないprocess.pole()です。代わりに

for i in range(nfuncs): 
    t=MyThread(funcs[i],(command,output)) 
    threads.append(t) 

for func in nfuncs: 
    t=MyThread(func,(command,output)) 
    threads.append(t) 

、なぜあなたはpython test.pyを実行しているのですか?あなたは、シェルでls communicateを実行するため、その場合には、あなたが何かやるべきことしたくない://ドキュメント:それを見てから

def bash(command,output): 
    process=Popen('bash',stdout=PIPE,stdin=PIPE,stderr=PIPE,shell=True) 
    print process.stdout.readlines() 
    # I don't really understand what's going on here 
    while (process.pole()==None): 
     print 'bash' 
     process.stdin.write(command.get(1)) 
     process.stdin.flush() 
     output.put(process.stdout.readlines(),1) 
     process.stdout.flush() 
+0

python test.pyはテスト目的のみでした。そして、poll()についてのハイライトに感謝します。私はあなたが提案した変更を加えましたが、それでも同じ問題が存在します。それはコマンドを求め、私はそれを入力し、それは通信を印刷し、それだけです。それはただ止まる。これは何が原因でしょうか? – Hashken

+0

stdinとstdoutを読み書きする代わりにPopen.communicate()を使ってみましたか?それらは状況によってはデッドロックすることが知られています。 – agf

+0

また、それがうまくいかない場合は、簡単にするためにスレッドを使わないでコードをデバッグする方が良いでしょう。 – agf

0

process.stdout.readlines()に掛かっている可能性はありますか?おそらく、行末が見つかりません。 stdout.read(1)を試して1文字を読み、何が起こるかを見てください。

+0

なぜ行終りが 'readlines()'を終了させるのでしょうか?行末で分割されることもありますが、ファイルの最後まで読み込まれます。 – agf

+0

pyserial入力でreadline()を使用して同様の問題が発生しました。行末がなければ、pyserialは待っていた。 「ファイル」がいつ終わるかを知る方法はありません。 Pyserialはシェルとはまったく違っていますが、私はそれを知っていますが、誰が知っていますか? – Remi

+0

問題は__file ending__がなかったことです。制限なしの 'read()'も掛かっていましたか? – agf