[Tutor] Threading in a for loop

Kent Johnson kent37 at tds.net
Fri Sep 23 04:54:36 CEST 2005


Here are some more resources for you.

This cookbook recipe is very similar to what you want to do, just customize workerThread1 to do the actual work. It shows how to use a Queue to communicate back to the GUI thread.
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/82965

Here are a couple of thread pool recipes - these will be useful if you decide you need multiple threads.
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/203871
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/435883

Threading is a complex subject and I don't have time and energy to do it justice right now. I hope these resources help.

Kent

Kent Johnson wrote:
> Bill Burns wrote:
> 
>>I've got a few questions regarding Threading. I've never used threads
>>before and I want to make sure I'm doing it correctly ;-)
>>
>>I have a GUI app and it processes Tiff files to PDF (or PostScript). The
>>GUI has a ListBox which the user populates with files to convert. You
>>click on a Button and the file conversion starts. When all the files
>>have been converted, the ListBox items (the files) are cleared.
>>
>>Initially, you had no way of knowing what was going on until all the
>>files where cleared from the ListBox.
>>
>>So I thought of creating threads in the 'for loop' and displaying the
>>name of each file in the statusBar of the GUI (as they are being
>>processed).
> 
> 
> You don't necessarily need threads for this. If you just want to provide feedback and don't care about the GUI being responsive, just do the processing in a loop, update the status bar and call root.update_idletasks() to allow the GUI to redraw. (Assuming you are using Tkinter.)
> 
> If you want the GUI to remain responsive so for example you can have a Cancel button, then I would make a single thread and process all the files in that thread. Don't sleep in the thread; call root.update() to give some time to event handling. Somehow you will have to notify the main thread that the worker thread is done.
> 
> The only reason I can think of to make a separate thread for each image is if the process is significantly I/O bound. My guess is that Tiff to PDF conversion is CPU-intensive and a single worker thread will be plenty.
> 
> More notes below...
>  
> 
>>Here's my method which takes the files in the ListBox and sends them off
>>to my Convert() class (self.convert = Convert()).
>><code>
>>def convertTiff2PDF(self):
>>     from time import time
>>     #Let's see how long this takes... I saw Kent do this on the
>>     #Python Tutor list before :-)
>>     start = time()
>>     #Grab a tuple which contains width & length
>>     sizes = self.getPaperSize()
>>     width = sizes[0]
>>     length = sizes[1]
>>     #Count the number of files in the ListBox
>>     fileCount = self.fileListBox.count()
>>     for index in range(fileCount):
>>         #Get each filename
>>         filenames = str(self.fileListBox.text(index))
>>         #Setup the worker thread and send the filenames in
>>         worker = WorkerThread(self, filenames)
>>         #Start threading
>>         worker.start()
>>         #Send each file to be converted
>>         self.convert.tiff2pdf(width, length, filenames)
> 
> 
> The above line should be in the thread, not in the main loop - you are spawning threads that do nothing but update the status display - and they will compete for that.
> 
> 
>>     #We're done, so clear the ListBox
>>     self.fileListBox.clear()
>>     #Check the time again
>>     end = time()
>>     msg = '%s Files Processed in %0.3f Seconds.' % (fileCount,
>>(end-start))
>>     #Grab the statusBar and insert the message
>>     statusBar = self.statusBar()
>>     statusBar.message(msg, 0)
>></code>
>>
>>And here's what I'm doing in my Thread class:
>><code>
>>class WorkerThread(Thread):
>>     """Thread class."""
>>     def __init__(self, parent, files):
>>         Thread.__init__(self)
>>         self.parent = parent
>>         self.files = files
>>
>>     def run(self):
>>         statusBar = self.parent.statusBar()
>>         msg = 'Processing: %s, please wait.' % (self.files)
>>         statusBar.message(msg, 100)
>>         time.sleep(1)
>></code>
>>
>>Am I doing this threading properly? Is it 'OK' to start multiple threads
>>like this (in the for loop)? It's possible that a user could put 'many'
>>files into the ListBox, by 'many' I mean 100-200 files.
> 
> 
> It's OK to have multiple threads but yours aren't doing any useful work.
> 
> I hope this helps get you on track, it's a bit brief.
> 
> Kent
> 
>>Thanks for your help.
>>
>>Bill
>>
>>
>>_______________________________________________
>>Tutor maillist  -  Tutor at python.org
>>http://mail.python.org/mailman/listinfo/tutor
>>
>>
> 
> 
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> http://mail.python.org/mailman/listinfo/tutor
> 
> 



More information about the Tutor mailing list