Threads modify "global" variable -- asking for trouble?
J Rice
rice.jeffrey at gmail.com
Thu Mar 16 22:58:36 EST 2006
I have been experimenting with some thread programming, but as I'm
doing this on my own I am worried I might be making a major mistake.
Here's a brief rundown of what I am working on. Multiple threads, via
Queue, are used to perform RBL checks on an IP. The threads are passed
a defined class (ConnectionScore) in their init. This is used to
collect the results, including a method to add the result. If I run
the program, everything goes fine and once all the threads complete the
main program has all the data from their RBL checks in the
ConnectionScore class.
It seems to work, even with an obscene (and silly) number of WORKERS
and RBLs to check. But I was reading in the Python Cookbook this
evening and it raised the issue in my mind of what happens if multiple
threads try to add data to the class at the same time.
I've attached the code below. The ConnectionClass.addRBL method just
takes the result and adds it to a dictionary object attached to the
class.
#!/usr/bin/python
from UCE_weight import ConnectionScore
from rbl import *
import Queue
import threading
import time, random
starttime = time.time()
WORKERS=5
class Worker(threading.Thread):
def __init__(self,queue,score):
self.__queue = queue
threading.Thread.__init__(self)
self.score = score
def run(self):
while 1:
RBL = self.__queue.get()
# Are we at the end of the queue?
if RBL is None: break
self.result = checkRBL("127.0.0.2",RBL,True,5)
score.addRBL(RBL,self.result[0],self.result[1])
queue = Queue.Queue(0)
score = ConnectionScore()
f = open("rbl.list",'r')
MEGARBL = []
while 1:
line = f.readline().strip()
if not line: break
MEGARBL.append(line)
f.close()
for i in range(WORKERS):
Worker(queue,score).start() # start a worker
for i in MEGARBL:
queue.put(i)
for i in range(WORKERS):
queue.put(None) # add end of queue marker
while 1:
# wait for the queue???
if queue.empty():
break
else:
time.sleep(0.1)
elapsed = time.time() - starttime
rate = len(MEGARBL)/elapsed
rate = str(round(rate,2))
elapsed = str(round(elapsed,2))
score.showRBL()
print "Checked",str(len(MEGARBL)),"zones in",elapsed,"seconds.
(",rate.strip(),"per second )"
More information about the Python-list
mailing list