问题描述
我有一个问题:我的主线程应该启动并加入一个线程,该线程的运行时间约为10-15秒.
所以:
- 我的主线程启动了一个子线程,该子线程必须运行大约10-15秒
- 我的主线程加入了子线程:主线程需要子线程的结果
- 在子线程运行的同时,我必须更新GUI ,它只是一个进度条(可能是每0.2秒)
- 更新GUI:我将使用递归函数
- 子线程完成,主线程获取结果
- my main thread starts a child thread, whom has to run about 10-15 seconds
- my main thread joins the child thread: the main thread needs the result of the child thread
- in the meanwhile the child thread runs, i've to update the GUI, it is just a progressbar (possibly every 0.2 second)
- updating the GUI: i'll use a recursive function
- the child thread finishes and the main thread gets the result
我的代码存在的问题是 Trovarete_Window仅在worker函数已经结束时出现并开始更新 .因此,我的程序会挂起/冻结,直到工作程序运行为止.
The problem with my code is that the Trovarete_Window appears and starts to be updated only when the worker function has already ended. So my program hangs/freezes until the worker runs.
这是我的代码:
def collega_GUI(widget, args=()):
builder.get_object('Trovarete_Window').show_all()
progressbar.set_pulse_step(0.20)
pulse()
t = threading.Thread(target=worker)
t.setDaemon(True)
t.start()
t.join()
print 'a'
def pulse():
if not event.is_set():
progressbar.pulse()
GObject.timeout_add(300, pulse)
def worker():
#hard work
推荐答案
问题是您正在collegea_GUI
内部调用t.join()
.调用t.join()
意味着您的主线程-运行事件循环的线程-被阻塞,直到worker
完成.只要您被阻塞在collegea_GUI
中,您的主循环就无法运行,这意味着您计划的对pulse
的调用将无法运行,并且GUI也无法更新.
The problem is that you're calling t.join()
inside collegea_GUI
. Calling t.join()
means your main thread - the thread that's running the event loop - is blocked until worker
completes. As long as you're blocked inside collegea_GUI
, your main loop cannot run, which means the call to pulse
you scheduled can't run, and the GUI can't be updated.
代替调用t.join()
,您需要执行与pulse
相似的操作-安排要运行的函数进行无阻塞检查,以查看worker
是否完成.像这样:
Instead of calling t.join()
, you'll need to do something similar to what you're doing with pulse
- schedule a function to run that does a non-blocking check to see if worker
is finished. Something like this:
def collega_GUI(widget, args=()):
builder.get_object('Trovarete_Window').show_all()
progressbar.set_pulse_step(0.20)
pulse()
t = threading.Thread(target=worker)
t.setDaemon(True)
t.start()
wait_for_t(t)
def wait_for_t(t):
if not t.is_alive():
t.join() # This won't block, since the thread isn't alive anymore
print 'a'
# Do whatever else you would do when join() (or maybe collega_GUI?) returns
else:
Gobject.timeout_add(200, wait_for_t, t)
这篇关于GObject.idle_add(),thread.join()和我的程序挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!