On Wed, Aug 27, 2014 at 11:55 AM, Ervin Hegedüs <airw...@gmail.com> wrote:
> what's the correct way to terminate a thread by itself? > To terminate the thread, the run function must exit. This can be either from an exception or a return statement. > > I mean: > > class MyThread(threading.Thread): > def __init__(self, queueitem): > threading.Thread.__init__(self) > ... > > def run(self): > """pseudo code below""" > > try: > self.connect_to_database() > except: > First off, especially if you are going to raise an exception anyways, I would recommend not silencing the orignal error - it will make debugging harder. This is especially true with a bare "except:" statement - at least capture only some exceptions. Using a logger to handle the exception or use your except, log the error, than reraise with a bare "raise" statement would generally be preferable. self.terminate("Error when connect to db") > > try: > self.create_db_table() > except: > self.terminate("Error when create table") > You probably want to make sure to disconnect from the database in here. Possibly via a "with" statement or a "try...finally" over the entire block, depending on your database API. .... > def terminate(self, msg): > self.error = True > self.errormsg = msg > syslog.syslog(syslog.LOG_DEBUG, msg) > raise Exception(msg) > > > in main(): > > for q in range(0, 10): > mt = MyThread() > try: > mt.run() > This is not actually starting a thread, but is running it in-line, just like a normal function. You probably want "mt.start()" instead, which will cause "mt.run" to execute in another thread. If you use mt.start() to actually start a thread, the only time it will fail is if the thread fails to start (such as too many running threads, or other out-of-resource errors). The exceptions raised inside the thread will not propagate outside the start call, and thus the mt.join() call inside the except statement will have no effect - no thread is running. except: > mt.join() > but it doesn't works - the exception showed on stdout only, and > the thread stops of course, but I would like to handle the > exceptions. If I call the join() inside from thread object, then > an exception raised, cause the thread object of Threading module > doesn't allows that... > Not being able to call join from the thread you are joining with is probably a good thing - doing so would result in a dead lock: the thread is waiting for the thread to exit. In your case, you may want to just handle the exceptions inside the thread's run() function directly. If that is not possible and you really need to handle them inside the main thread, you would need to store off the error data in a variable (either passed into the thread as the "args" or "kwargs" arguments to the MyThread() call, or global or class variables) then use mt.join() to wait for the thread(s) to exit. In the case of handling the problems in the main thread, your main thread code would look something like: # Start all of the threads up-front. threads = [] for q in range(0, 10): mt = MyThread() mt.start() # NOT mt.run() - that does not do any threading! threads.append(mt) # Now wait for them to complete. for thread in threads: thread.join() # Check for the status of thread here. Possibly on the thread object, which can be mutated in MyThread.run by assigning to members of self. In the sample code you are doing, I am not even sure if I would use threads due to the added complexities associated with them. In the case of merely connecting to a database and creating a few tables, you can probably get by with doing them in a single thread: open a single connection, creating the tables as a sequence of operations, commit operations, and close connection. If you do in fact need threads, you may also be better off using a thread pool (see concurrent.futures, available in Python 3.2 and higher only). This can reduce the overhead associated with threads and provide better performance - both locally and, with database connections, on the server.
-- https://mail.python.org/mailman/listinfo/python-list