Threading:
T.setdaemon (True) sets the thread as the daemon thread, and the thread is forced to end after the master has finished. If the thread does not set this value, it waits for the thread to execute after the main thread has finished executing.
T.join () thread is blocked and will continue to execute subsequent statements only after the thread has finished running
Example:
#Coding:utf-8ImportThreadingImport Timedeffoo (name): Time.sleep (2) Print 'This is %s \ n'%(name,)if __name__=='__main__': Mythread= [] forIinchRange (5): T= Threading. Thread (Target=foo, args=(i,))#T.setdaemon (True)T.start () mythread.append (t)#For T in Mythread:#T.join () Print '--End- -'
Run results (note that print is not thread-safe, so the printed content is sometimes messy):
--End--
This is 1
This is 2
This is 4
This is 0
This is 3
Process finished with exit code 0
As you can see, the main thread and the child threads are running independently (the last line is first printed), and the main thread is still waiting for the child thread to end after it finishes running.
Uncomment the above T.setdaemon (True) and run it again, and find that only the following is printed:
--End--
Process finished with exit code 0
That is, after the main thread runs, it forces the end of the child thread
Let's go ahead and remove the note below.
# for T in Mythread:
# T.join ()
Run again and the output is as follows:
This is 1
This is 0
This is 3
This is 4
This is 2
--End--
Process finished with exit code 0
Note: End is output at the end, indicating that the main thread is blocked from running in the join, waiting for the child thread to run to complete.
Queue
Q.put (item) puts the item in the queue.
Q.get () extracts data from the queue.
Q.task_done () After getting a data from the queue each time, when dealing with the related problems, and finally call the method to indicate whether Q.join () stop blocking, let the thread forward or exit;
Q.join () blocks until the data in the queue has been task_done processed to empty.
If you do not use Task_done, you can judge by Q.full () q.empty (), etc.
Q.join () Hidden issues:
For the producer-consumer model, this blocking method is vulnerable because if the queue is initially empty, q.join () stops blocking directly and continues to execute the subsequent statements.
There is another situation, that is, producer production speed is relatively slow, and consumer consumption speed is relatively fast, it is possible to stop blocking, continue to execute the subsequent statements
If there are multiple consumers, there is no producer, and the queue begins to be a certain amount of data, it can be executed normally.
Example:
#Coding:utf-8ImportQueueImportThreadingImportTimequeue= Queue.queue (maxsize=3)defProduce (): forIinchRange (5): Item="Item"+Str (i) queue.put (item)Print "%s Produce"%(item,)#Time.sleep (4) defcustomer (): whileTrue:time.sleep (2) Item=Queue.get ()Print "Process%s finished"%(item,) Queue.task_done ()if __name__=='__main__': T= Threading. Thread (target=produce) T.setdaemon (True) T.start () forIinchRange (3): C= Threading. Thread (target=customer) C.setdaemon (True) C.start () Queue.join ()Print '--End- -'
Run the output as follows:
ITEM0 Produce
ITEM1 Produce
ITEM2 Produce
Process Item0 finished
Process Item2 finishedprocess Item1 finished
ITEM3 Produce
ITEM4 Produce
Process Item3 finished
Process Item4 finished
--End--
Process finished with exit code 0
You can see that the program ends properly and the end character is printed at the end.
Let's comment out the following statement in the produce function,
Queue.put (item)
Print "%s Produce"% (item,)
Run to get:
--End--
Process finished with exit code 0
That is, the queue is empty, and the join () method does not block the thread.
We add sleep to the produce function to make the production slower, remove the comments from the front of the Time.sleep (4) and run it:
ITEM0 Produce
Process Item0 finished
--End--
Process finished with exit code 0
Sometimes running may get this error message:
Exception in thread Thread-3 (most likely raised during interpreter shutdown)
The error message indicates that the main thread does not wait for the child threads to end.
Can be found, in fact, produce function should have a task to generate, but because too slow, in the join statement there is detected that the queue has been all set Task_done, will continue to execute, which may sometimes not we need, in response to this situation, We can do this by adding one more clause t.join () before Queue.join ().
If we get rid of the Queue.task_done () function in the customer function, we can run the
ITEM0 Produce
Process Item0 finished
ITEM1 Produce
Process Item1 finished
ITEM2 Produce
Process Item2 finished
ITEM3 Produce
Process Item3 finished
ITEM4 Produce
Process Item4 finished
Note that the program never ends, and the last line end statement does not appear. Because at join there, although the queue is already all consumed, is already 0, but because it is not called the Task_done function and let it count to 0, so at this time, the function will be blocked here.
How to use Join Setdaemon and Task_done in the Python Threading queue module and examples