GObject.idle_add(), thread.join() and my program hangs

余生长醉 提交于 2019-12-25 00:05:24

问题


I've a problem: my main thread should start and join a thread that has a to run about 10-15 seconds.

So:

  • 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

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.

Here is my code:

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

回答1:


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.

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)


来源:https://stackoverflow.com/questions/26172107/gobject-idle-add-thread-join-and-my-program-hangs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!