[英]How to terminate a process using multiprocessing in Python?
当我单击srch
按钮时, srch_kwrds1
被执行,我预计当我单击stp
按钮时,函数srch_kwrds1
将终止,输出到控制台的值为 0,但输出为 0 后跟 1 意味着srch_kwrds1
并未真正终止。 如何终止srch_kwrds1
?
from bokeh.models.widgets import Button, Div
from bokeh.layouts import column
from bokeh.io import curdoc
import time
from multiprocessing import Process
class Callbacks:
def __init__(self):
self.i = 0
def srch_kwrds1(self):
time.sleep(5)
layout.children[2] = Div(text='done!')
print(self.i + 1)
def srch_kwrds(self):
layout.children.insert(2, srch_txt)
self.p = Process(target=self.srch_kwrds1)
self.p.start()
def stp_srch(self):
self.p.terminate()
srch_txt.text = 'stopped'
print(self.i)
cb = Callbacks()
srch = Button(label='search')
srch.on_click(cb.srch_kwrds)
stp = Button(label='stop')
stp.on_click(cb.stp_srch)
srch_txt = Div(text='searching')
layout = column(srch, stp)
curdoc().add_root(layout)
当我只是按下strt
按钮时,布局不会更新以显示“完成!”。 如何更新布局?
我在Bokeh Discourse 中问过这个问题,但我没有在那里得到答案,因为这个问题更像是一个多处理问题而不是 Bokeh 问题,我认为在那里进一步追问是不合适的。
Python 中的 multiprocessing 模块默认不共享内存。 您的 GUI 正在您的原始进程中运行; 新进程无法直接访问它。 我建议改用线程或设置SharedMemory
对象以在进程之间来回传递数据。
多线程将允许您在进行搜索的同时做其他事情,但不会让您充分利用多个 CPU 内核。 它还允许在线程之间共享内存,前提是您使用了适当的措施,例如互斥锁(查看类Lock
Python 文档),以确保没有两个线程以冲突的方式同时访问相同的内存。 根据您的应用程序,这可能没问题。 如果您希望多个 CPU 内核同时执行不同的操作,那么您可以使用多处理实现真正的并发,但同样需要明确设置内存共享。 我建议不要共享 GUI 数据,因为这通常非常相互关联且依赖于流程。 由于您正在进行搜索,您应该会发现共享字符串和类似的简单数据更容易,然后主进程可以读取并在 GUI 上显示。
作为使用线程和 tkinter GUI 的示例:
from tkinter import *
from threading import Thread, Lock
thread = None
stop = None
search_result_label = None
label_lock = Lock()
def do_search():
global stop
global search_result_label
global label_lock
s = 0
for i in range(10000):
for j in range(10000):
s += i * j
if stop:
return
with label_lock:
search_result_label["text"] = "Search result: {}".format(s)
def start_search():
global thread
global stop
thread = Thread(target = do_search)
stop = False
thread.start()
def stop_search():
global stop
global search_result_label
global label_lock
stop = True
with label_lock:
search_result_label["text"] = "Search stopped"
root = Tk()
div = Frame(root)
div.grid()
search_button = Button(div, text = "Search")
search_button["command"] = start_search
search_button.grid(row = 0, column = 0)
stop_button = Button(div, text = "Stop")
stop_button["command"] = stop_search
stop_button.grid(row = 0, column = 1)
search_result_label = Label(div, text = "Empty results")
search_result_label.grid(row = 1, column = 0, columnspan = 2)
root.mainloop()
当然,您可能不会只是在搜索函数中按顺序添加一亿个数字,但大多数计算密集型函数都有某种循环,您可以通过该循环检查每次是否设置了停止。 不幸的是,停止线程并不像调用某个方法 terminate() 那样简单(尽管在许多情况下您无论如何都不想这样做,因为它可能导致内存泄漏和其他问题)。 请注意我如何使用锁来访问标签,因为它可以被多个线程访问。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.