On Oct 20, 5:55 am, Steven D'Aprano <steve +comp.lang.pyt...@pearwood.info> wrote: > On Wed, 19 Oct 2011 13:14:21 -0700, markus.mj wrote: > > Hi, > > > I am looking for help with following problem. I scripted threaded > > database query, with session open per thread, and queries delivered > > through queue. Every open DB session must be closed with "abort" or > > "commit", however on which event should I trigger the DB disconnect? > > Ideally it would close the DB as the thread class gets deconstructed, > > but "__del__" does never fire. > > The __del__ destructor method is not guaranteed to be called in a timely > fashion, if at all. My *guess* is that the main Python environment is > shutting down when the daemon threads get killed, and the __del__ method > never gets a chance to run. > > To be honest, I'm not sure why you are using daemon threads. It seems to > me that blocking until the queue is empty makes the use of daemon threads > pointless, but I'm not experienced enough with threads to be sure. > > The usual advice is to explicitly call destructors rather than rely on > automatic __del__ methods. Given that, this works for me: > > import threading > import Queue > import time > > # Fill the queue. > queue = Queue.Queue() > queries = ["query"+str(i) for i in range(10)] > for query in queries: > queue.put(query) > > # Make consumer threads. > class ThreadSql(threading.Thread): > def __init__(self, queue): > threading.Thread.__init__(self) > self.queue = queue > # Open database connection instance > self.session = "+++connection+++" # DbConnect() > self._open = True > > def run(self): > while self._open: > # Grab a query from queue. > query = self.queue.get() > # And process it. > print self, query > time.sleep(1) > # Mark the queue job as done. > self.queue.task_done() > > def close(self): > print "Closing", self > # self.session.Disconnect(<abort, commit>) > self._open = False > > threads = [ThreadSql(queue) for _ in range(4)] > for t in threads: > t.setDaemon(True) > t.start() > > # Wait until the queue is empty, then close the threads. > queue.join() > for t in threads: > t.close() > > -- > Steven
Hi Steven, great point with the explicit call of destructor. I did a quick test and it is behaving exactly like I need. Thank you very much! Markus -- http://mail.python.org/mailman/listinfo/python-list