2017-06-27 5 views
0

私はこのテーマでいくつかの検索を行ってきましたが、私の質問には非常に明確な答えはないようです。私は現在、ユーザーがボタンをクリックして一度Python関数reply()を呼び出すと、関数は2つの異なるスレッド、a(オーディオを表す)を開始し、r(ルーチンを表す)という2つのスレッドが想定されています。一緒に働くと基本的にはナレーターとしてベースマップで方向を指すようにして話す:関数にアクセスし、Pythonのメディアとサーボのサブプロセスのスレッドを停止します

def reply(index, path2, path3): 
    a = threading.Thread(target=playaudio(path3)) 
    r = threading.Thread(target=routine(path2)) 
    r.start() 
    a.start() 

機能にアクセスし、ユーザーのplayaudioroutine機能の両方のためにそれらのスレッドを停止する方法があれば、私は疑問に思って停止ボタンをクリックすると、ユーザーがもう見たいと思わない場合は、プレゼンテーションを停止するだけです。二つの機能は以下のように設定されています

# play audio function starts here: 
def playaudio(path): 
    try: 
     subprocess.Popen(["mpg123", path]) 

    except Exception as ex: 
     tkMessageBox.showinfo('Error', 'An error occurred. ' + str(ex)) 

# routine function starts here 
# routine controls the servo module 
def routine(path): 
    with open(path, 'rb') as f: 
     reader = csv.reader(f) 
     settings = list(reader) 

    print(settings) 
    i = 1 
    while i < (len(settings) - 1): 
     try: 
      setall(int(settings[i][1]), int(settings[i][2]), int(settings[i][3]), int(settings[i][4])) 
      delay = float(settings[i+1][0]) - float(settings[i][0]) - 0.015 #includes processing time 
      time.sleep(delay) 
      i += 1 
     except Exception as ex: 
      pass 
    setall(int(settings[i][1]), int(settings[i][2]), int(settings[i][3]), int(settings[i][4])) 

これらは、メイン画面上のTkinter.Button要素で開始され、オーディオの両方を再生し、サーボモジュールを制御します。停止機能については

button = Tkinter.Button(window, text='Audio 4', command=lambda: reply(1, 'path/to/excel/file.csv', '/path/to/audio/file.mp3')) 
button.config(width="30", height="5") 
button.place(x=490, y=40) 

は、私は別の Tkinter button要素を追加するための解決策になるだろうと思ったが、ユーザがそれをクリックするたびに異なる機能を subprocessを終了します。実際 stop()機能については

stop_button = Tkinter.Button(window, text='Stop Audio', command=lambda: stop()) 
stop_button.config(width="30", height="5") 
stop_button.place(x=490, y=360) 

私は、このようなstop()destroy()など、いくつかの方法を試みたが、オーディオのいずれかまたはサーボが実行を継続、または実際のプログラムが停止します。

私の質問は、どうすれば違うのですか?私はこの問題のフィードバックを本当に感謝します。

答えて

1

Queue moduleを調べましたか?メッセージをスレッドに送ることができます。

だから、あなたがスレッド機能にアクセス可能であるqQueueのインスタンス)を持って想定し、あなたのroutine()スレッド関数は次のようになります:

def routine(path): 

    # skip some stuff... 

    while i < (len(settings) - 1): 
     if not q.empty(): 
      message = q.get() 
      if message == 'stop': 
       break 

     # rest of your function 

をごplayaudio()機能では、あなたがしたいと思いますあなたが作成したオブジェクトPopenを保持し、 `terminate()メソッドを使ってプロセスを終了します。それを行う方法の詳細については、subprocessのドキュメントをご覧ください。あまりにもマルチモジュールを見て取り、余談として

def stop(): 
    q.put('stop') 

:ユーザーが「停止」ボタンをクリックしたときに

次に、あなたがキューにメッセージを投稿することができます。 PythonのGILは、スレッドが正しく実行されるのを防ぎ、マルチプロセスはそれを回避し、複数のコアを利用することができます。

+0

これはうまくいかないようです。私のサーバーからのすべての応答が失われたので、実際にルーチン機能が動作を停止しているように見えました。理由は何ですか? – Samuel

+1

Queue.Queueのドキュメントを参照してください。おそらく実際にq.get_nowait()を使用して例外をキャッチしたいと思うでしょう。 –

関連する問題