1

I wrote a python GUI program to deal with some scientific calculations. One of the functions was extremely time consuming so that I wish to put it into a separate thread so that running it will not block the entire program.

The problem is that this thread does not actually starts (or queue.get never obtains a result).

However, if I passed the option block = True into the self.PLUQ = self.queue.get(block = False) statement, the function will execute but will also block the entire program.

    Class PLUQ_GUI_Dialog():
        #somefunctions to initiatialize the class 

        def guess_button_click_cb(self):
            self.selected_peaks = self.session.selected_peaks()
            if (not self.is_ready_to_guess()):
                return
            self.input_frequencies = self.get_input_frequencies(self.selected_peaks)

            self.queue = Queue.Queue()
            thread = threading.Thread(target = self.guess, args = (self.queue, self.input_frequencies))
            thread.setDaemon(True)
            thread.start()
            self.top.after(100, self.process_queue)

        def guess(self, queue, inputs):
            PLUQ = pluq.PLUQ_interface() 
            #pluq is a separate python module
            PLUQ.query(inputs)
            #query does some calculations and put results in the PLUQ object
            queue.put(PLUQ)

        def process_queue(self):
            try:
                self.PLUQ = self.queue.get(block = False)
                self.update_pluq_result() # This will display the result
            except Queue.Empty:
                self.top.after(100, self.process_queue)

        #some helper function
LH2
  • 131
  • 2
  • 3
  • Does it work if you replace `guess()` with `time.sleep(1); queue.put(1+1)`? Related: [Python threading.thread.start() doesn't return control to main thread](http://stackoverflow.com/q/22138190/4279) – jfs Mar 05 '14 at 02:15
  • I replaced the content of guess into time.sleep(10) and queue.put(1), however, whatever in the try block (say, a print statement after self.queue.get) still won't be evaluated. ALso, thread.is_alive() after thread.start() will return True. – LH2 Mar 06 '14 at 20:07
  • if it doesn't work even with `time.sleep(10); queue.put(1)` then the issue is in your code. Could you post a [complete minimal code example](http://stackoverflow.com/help/mcve) that demonstrates the issue? – jfs Mar 06 '14 at 20:14
  • I'm still not sure what the problem is. I'm guessing it's related with GIL. Anyway, I got around the problem by using multiprocessing.Process instead of threading.Thread. The interface is basically identical. – LH2 Mar 06 '14 at 22:58

2 Answers2

0

.setDaemon() is part of the Python 2.6 and earlier API. You should now be setting your daemon threads like so:

self.queue = Queue.Queue()
thread = threading.Thread(target = self.guess, args = (self.queue, self.input_frequencies))
thread.daemon = True # like this
thread.start()
self.top.after(100, self.process_queue)

You can read more about it here.

Drewness
  • 5,004
  • 4
  • 32
  • 50
  • 1. `.setDaemon()` is deprecated but it works. 2. OPs issue is unrelated to whether the thread is daemonic or not. – jfs Mar 05 '14 at 02:20
0

The problem could be GIL related. I got around the problem by using multiprocessing.Process instead of threading.Thread.

LH2
  • 131
  • 2
  • 3