Threading: Method trigger after thred finished
Markus
markus.mj at gmail.com
Thu Oct 20 03:05:27 EDT 2011
On Oct 20, 5:55 am, Steven D'Aprano <steve
+comp.lang.pyt... at 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
More information about the Python-list
mailing list