在 python 中访问函数并停止穿线介质和伺服子进程
Access function and stop threading media and servo subprocess in python
我一直在搜索这个主题,但我的问题似乎没有一个非常明确的答案。我目前正在做一个项目,用户点击一个按钮,一旦他点击了,我就调用一个 python 函数,reply()
,该函数启动两个不同的线程,a
(代表音频)和 r
(代表例程)这两个线程应该一起工作,并且基本上指向地图中的一个方向,正如叙述者所说:
def reply(index, path2, path3):
a = threading.Thread(target=playaudio(path3))
r = threading.Thread(target=routine(path2))
r.start()
a.start()
我想知道是否有一种方法可以在用户单击停止按钮时访问该函数并停止 playaudio
和 routine
函数的那些线程,这样如果用户没有再想看,他需要做的就是停止演示。两个函数设置如下:
# 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
按钮元素是一种解决方案,但具有不同的功能,可以在用户单击它时退出 subprocess
。
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()
功能,我尝试了一些方法,例如 stop()
和 destroy()
,但是音频或伺服继续 运行,或者实际程序关闭。
所以我的问题是,我应该采取哪些不同的做法?如果您对此问题有任何反馈,我将不胜感激。
你看过 Queue module 了吗?您可以使用它向线程发送消息。
因此,假设您的线程函数可以访问 q
(Queue
的一个实例),您的 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 文档以获取有关如何执行此操作的更多信息。
然后,当用户单击 "stop" 按钮时,您可以 post 向队列发送消息:
def stop():
q.put('stop')
顺便说一句,也看看多进程模块。 Python 的 GIL 阻止线程正常发生,多进程能够绕过这个问题并利用多个内核。
我一直在搜索这个主题,但我的问题似乎没有一个非常明确的答案。我目前正在做一个项目,用户点击一个按钮,一旦他点击了,我就调用一个 python 函数,reply()
,该函数启动两个不同的线程,a
(代表音频)和 r
(代表例程)这两个线程应该一起工作,并且基本上指向地图中的一个方向,正如叙述者所说:
def reply(index, path2, path3):
a = threading.Thread(target=playaudio(path3))
r = threading.Thread(target=routine(path2))
r.start()
a.start()
我想知道是否有一种方法可以在用户单击停止按钮时访问该函数并停止 playaudio
和 routine
函数的那些线程,这样如果用户没有再想看,他需要做的就是停止演示。两个函数设置如下:
# 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
按钮元素是一种解决方案,但具有不同的功能,可以在用户单击它时退出 subprocess
。
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()
功能,我尝试了一些方法,例如 stop()
和 destroy()
,但是音频或伺服继续 运行,或者实际程序关闭。
所以我的问题是,我应该采取哪些不同的做法?如果您对此问题有任何反馈,我将不胜感激。
你看过 Queue module 了吗?您可以使用它向线程发送消息。
因此,假设您的线程函数可以访问 q
(Queue
的一个实例),您的 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 文档以获取有关如何执行此操作的更多信息。
然后,当用户单击 "stop" 按钮时,您可以 post 向队列发送消息:
def stop():
q.put('stop')
顺便说一句,也看看多进程模块。 Python 的 GIL 阻止线程正常发生,多进程能够绕过这个问题并利用多个内核。