Setting a scene, the user add multiple tasks, click the button to run task processed in the background of these tasks, and determine the success or failure of the task, because the task is time-consuming, so the use of multiple threads processing tasks
consider:
How to obtain the results of the implementation task threads started?
Look at the code:
Import Threading Import Time class TaskThread (of the threading.Thread): "" " processing task related to thread class " "" DEF the __init__ (Self, FUNC, args = ()): . Super (TaskThread, Self) the __init__ () self.func FUNC = # task to perform the type of self.args = args # to the incoming parameters DEF RUN (Self): # thread class instance calls the start () method will execute run () method, defined here to do a specific task asynchronous print ( " Start FUNC {} " .format (self.func. the __name__ )) #Print task name in the method name name__ .__ self.result = self.func (* self.args) # will be assigned to the task execution results self.result variable DEF get_result (Self): # change the method returns the results of task execution function, method name not necessarily get_result the try : return self.result the except Exception AS EX: Print (EX) return " ERROR " DEF task_type1 (task_id, task_name): Print ( " Start Tasks, name: {}, ID: {} " .format ( task_name, task_id)) the time.sleep ( 2 ) Print ( "Tasks End, name: {}, ID: {} " .format (task_name, task_id)) return task_id thread_pool = [] # listing for holding thread instance for I in Range (10 ): # Create a thread target loop thread = TaskThread (task_type1, args = (i + 1, ' the Pay ' )) # Add the thread object to the pool thread_pool.append (the thread) # start thread execution Tasks Thread.start () for the thread in thread_pool: # important step, why must to the Join Thread.join () # get the results from the thread pool in print("result:{}".format(thread.get_result()))
operation result:
start func task_type1 start tasks, name:pay, id:1 start func task_type1 start tasks, name:pay, id:2 start func task_type1 start tasks, name:pay, id:3 start func task_type1 start tasks, name:pay, id:4 start func task_type1 start tasks, name:pay, id:5 start func task_type1 start tasks, name:pay, id:6 start func task_type1 start tasks, name:pay, id:7 start func task_type1 start tasks, name:pay, id:8 start func task_type1 start tasks, name:pay, id:9 start func task_type1 start tasks, name:pay, id:10 end tasks, name:pay, id:4 end tasks, name:pay, id:2 end tasks, name:pay, id:1 end tasks, name:pay, id:5 end tasks, name:pay, id:8 end tasks, name:pay, id:3 result:1 result:2 end tasks, name:pay, id:9 result:3 result:4 result:5 end tasks, name:pay, id:10 end tasks, name:pay, id:6 result:6 end tasks, name:pay, id:7 result:7 result:8 result:9 result:10
The above code implements creating a thread execution task, and get the task, the key point is that the thread class implements ge_result methods used to obtain the task function's return value, and uses thread.join (), this is a must, if there is no thread .join () will be what will happen?
Commented: thread.join () and re-run the code:
start func task_type1 start tasks, name:pay, id:1 start func task_type1 start tasks, name:pay, id:2 start func task_type1 start tasks, name:pay, id:3 start func task_type1 start tasks, name:pay, id:4 start func task_type1 start tasks, name:pay, id:5 start func task_type1 start tasks, name:pay, id:6 start func task_type1 start tasks, name:pay, id:7 start func task_type1 start tasks, name:pay, id:8 start func task_type1 start tasks, name:pay, id:9 start func task_type1 start tasks, name:pay, id:10 'TaskThread' object has no attribute 'result' result:ERROR 'TaskThread' object has no attribute 'result' result:ERROR 'TaskThread' object has no attribute 'result' result:ERROR 'TaskThread' object has no attribute 'result' result:ERROR 'TaskThread' object has no attribute 'result' result:ERROR 'TaskThread' object has no attribute 'result' result:ERROR 'TaskThread' object has no attribute 'result' result:ERROR 'TaskThread' object has no attribute 'result' result:ERROR 'TaskThread' object has no attribute 'result' result:ERROR 'TaskThread' object has no attribute 'result' result:ERROR end tasks, name:pay, id:1 end tasks, name:pay, id:3 end tasks, name:pay, id:2 end tasks, name:pay, id:5 end tasks, name:pay, id:6 end tasks, name:pay, id:7 end tasks, name:pay, id:4 end tasks, name:pay, id:8 end tasks, name:pay, id:9 end tasks, name:pay, id:10
If you do not join, we got this result, which is why?
This is because self.result in the run method, only self.func after the execution, self.resultb was only assignment, when we call get_result, run method does not perform end, self.result naturally not assigned, so throw the 'TaskThread' object has no attribute ' result' exception.
Why join later can get self.result normal?
It is necessary to understand how the principles of multi-threading:
1. When a process starts, it will generate a default main thread, since the thread is the smallest unit of program execution flow when setting multiple threads, the main thread creates multiple child threads, in in python, (in fact, setDaemon (False)), the main thread after the completion of the implementation of its mandate, withdrew from the default, then the child thread will continue to perform their tasks
2. If setDaemon (True) method, set the child thread is daemon thread, the main thread once the execution is completed, the entire thread is terminated all executed, the situation may arise is that the child thread the task is not yet fully implemented the end, it was forced to stop, of course, this is not what we want to see
3. we want to see the results after the end of the main thread is blocked waiting for child thread execution is completed, then you need to use join ()
that can join () on the start () behind it?
Try:
Thread.start ()
Thread.join ()
The results:
start func task_type1 start tasks, name:pay, id:1 end tasks, name:pay, id:1 start func task_type1 start tasks, name:pay, id:2 end tasks, name:pay, id:2 start func task_type1 start tasks, name:pay, id:3 end tasks, name:pay, id:3 start func task_type1 start tasks, name:pay, id:4 end tasks, name:pay, id:4 start func task_type1 start tasks, name:pay, id:5 end tasks, name:pay, id:5 start func task_type1 start tasks, name:pay, id:6 end tasks, name:pay, id:6 start func task_type1 start tasks, name:pay, id:7 end tasks, name:pay, id:7 start func task_type1 start tasks, name:pay, id:8 end tasks, name:pay, id:8 start func task_type1 start tasks, name:pay, id:9 end tasks, name:pay, id:9 start func task_type1 start tasks, name:pay, id:10 end tasks, name:pay, id:10 result:1 result:2 result:3 result:4 result:5 result:6 result:7 result:8 result:9 result:10
The result is got, but each join after the start (), then the child thread to block the implementation of the end began to know the next cycle, the efficiency of such a cycle is equivalent to a single-threaded, if a task execution thread 2 seconds, in such a way that will perform 10 tasks 20s, obviously wrong usage, because the role of join () are: thread synchronization, ie after the end of the main thread task, enter the blocked state, has been waiting for after the end of the implementation of other sub-thread, the main thread to terminate