threading - race condition?

skunkwerk skunkwerk at gmail.com
Fri May 9 11:40:38 EDT 2008


On May 9, 12:12 am, John Nagle <na... at animats.com> wrote:
> skunkwerk wrote:
> > i'm getting the wrong output for the 'title' attributes for this
> > data.  the queue holds a data structure (item name, position, and list
> > to store results in).  each thread takes in an item name and queries a
> > database for various attributes.  from the debug statements the item
> > names are being retrieved correctly, but the attributes returned are
> > those of other items in the queue - not its own item.  however, the
> > model variable is not a global variable... so i'm not sure what's
> > wrong.
>
> > i've declared a bunch of workerthreads(100) and a queue into which
> > new requests are inserted, like so:
>
> > queue = Queue.Queue(0)
> >  WORKERS=100
> > for i in range(WORKERS):
> >    thread = SDBThread(queue)
> >    thread.setDaemon(True)
> >    thread.start()
>
> > the thread:
>
> > class SimpleDBThread ( threading.Thread ):
> >    def __init__ ( self, queue ):
> >            self.__queue = queue
> >            threading.Thread.__init__ ( self )
> >    def run ( self ):
> >            while 1:
> >                    item = self.__queue.get()
> >                    if item!=None:
> >                            model = domain.get_item(item[0])
> >                            logger.debug('sdbthread item:'+item[0])
> >                            title = model['title']
> >                            scraped = model['scraped']
> >                            logger.debug("sdbthread title:"+title)
>
> > any suggestions?
> > thanks
>
>    Hm.  We don't have enough code here to see what's wrong.
> For one thing, we're not seeing how items get put on the queue.  The
> trouble might be at the "put" end.
>
>    Make sure that "model", "item", "title", and "scraped" are not globals.
> Remember, any assignment to them in a global context makes them a global.
>
>    You should never get "None" from the queue unless you put a "None"
> on the queue.  "get()" blocks until there's work to do.
>
>                                         John Nagle

thanks John, Gabriel,
  here's the 'put' side of the requests:

def prepSDBSearch(results):
	modelList = [0]
	counter=1
	for result in results:
		data = [result.item, counter, modelList]
		queue.put(data)
		counter+=1
	while modelList[0] < len(results):
		print 'waiting...'#wait for them to come home
	modelList.pop(0)#now remove '0'
	return modelList

responses to your follow ups:
1)  'item' in the threads is a list that corresponds to the 'data'
list in the above function.  it's not global, and the initial values
seem ok, but i'm not sure if every time i pass in data to the queue it
passes in the same memory address or declares a new 'data' list (which
I guess is what I want)
2)  john, i don't think any of the variables you mentioned are
global.  the 'none' check was just for extra safety.
3)  the first item in the modelList is a counter that keeps track of
the number of threads for this call that have completed - is there any
better way of doing this?

thanks again



More information about the Python-list mailing list