Multithreading how about get the return value

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

    

 

 

 


  

 

Guess you like

Origin www.cnblogs.com/wangbaojun/p/11299424.html