Python concurrent programming Multi-Threading

Source: Internet
Author: User

Two ways to turn on threads:

 fromThreadingImportThreadImport TimedefSayhi (name): Time.sleep (2)    Print('%s Say hello'%name) if__name__=='__main__': T=thread (target=sayhi,args= ('Egon',)) T.start ()Print('Main Thread')
Way One
 fromThreadingImportThreadImport TimeclassSayhi (Thread): def__init__ (self,name): Supper ().__init__() Self.name=namedefRun (self): Time.sleep (2):        Print('%s Say hello'%self.name)if __name__=='__main__': T=say ('Egon') T.start ()Print('Main Thread')
Mode two

Here, I'm going to explain to them who's starting fast.

 fromThreadingImportThread fromMultiprocessingImportProcessImportOSdefWork ():Print('Hello')if __name__=='__main__':    #to open a thread under the main processT=thread (target=Work ) T.start ()Print('Main thread /master process')    " "print Result: Hello main thread/main process" "    #to open a child process under the main processT=process (target=Work ) T.start ()Print('Main thread /master process')    " "Print Result: main thread/main process Hello

Obviously we can see that in the thread the thread is printed first, and the main process is printed and then the child process is printed in the process. (Here I want to say briefly, that is, you start a process, you have to regain resources, however, when the thread is open, the resources already exist, do not need to open up new resources, so it will be significantly faster to open the speed of a lot)

Add: Open a thread, there is a process above him, we turn on the thread when the automatic generation of a thread, which is called the main thread, the thread is called another thread (why is not called a child thread, it is because here the thread he just shared resources, there is no dependency between them)

Let's talk about this: threads in the same process share the process's data (resources)

 fromThreadingImportThread fromMultiprocessingImportProcessImportOSdefWork ():GlobalN N=0if __name__=='__main__':    #n=100    #p=process (target=work)    #P.start ()    #P.join ()    #print (' main ', N) #毫无疑问子进程p已经将自己的全局的n改成了0, but only to its own, to view the parent process n is stillN=1T=thread (target=Work ) T.start () T.join ()Print('Master', N)#View the result as 0 because the in-process data is shared among threads in the same process

(Here I would like to briefly explain why a thread in the same process can share the data of the process, from this instance we can clearly see that in the process, the child process, he just changed his n to 0, and the parent process of n is always 100, and for the thread that the result of N is 0, which is because, Threads in the same process share the process's data)

Example: three tasks, one receiving user input, one will format the user input into uppercase, a formatted result into a file (first, in this case three tasks are executed simultaneously,)

 fromThreadingImportthreadmsg_l=[]format_l=[]defTalk (): whiletrue:msg=input ('>>:'). Strip ()if  notMsgContinuemsg_l.append (msg)defformat_msg (): whileTrue:ifMsg_l:res=Msg_l.pop () format_l.append (Res.upper ())defSave (): whileTrue:ifFormat_l:with Open ('Db.txt','a', encoding='Utf-8') as F:res=Format_l.pop () f.write ('%s\n'%Res)if __name__=='__main__': T1=thread (target=Talk ) T2=thread (target=format_msg) T3=thread (target=save) T1.start () T2.start () T3.start ()

Other thread-related methods:

methods  for thread instance objects # isAlive (): Returns whether the thread is active.   #  getName (): Returns the thread name.   #  setName (): Sets the thread name.  Some of the methods provided by the  threading module are:#  threading.currentthread (): Returns the current thread variable.   #  threading.enumerate (): Returns a list that contains the running thread. Running refers to threads that do not include pre-and post-termination threads until after the thread has started and ends.   #  threading.activecount (): Returns the number of running threads with the same result as Len (Threading.enumerate ()). Copy Code
 fromThreadingImportThreadImportThreading fromMultiprocessingImportProcessImportOSdefWork ():ImportTime Time.sleep (3)    Print(Threading.current_thread (). GetName ())if __name__=='__main__':    #to open a thread under the main processT=thread (target=Work ) T.start ()Print(Threading.current_thread (). GetName ())Print(Threading.current_thread ())#Main Thread    Print(Threading.enumerate ())#along with the main thread, there are two running threads within    Print(Threading.active_count ())Print('Main thread /master process')    " "Printed results: Mainthread <_mainthread (Mainthread, started 140735268892672) > [<_mainthread (Mainthread, S tarted 140735268892672), <thread (Thread-1, started 123145307557888);] Main thread/main process Thread-1" "

The main thread waits for the child thread to end

Copy Code fromThreadingImportThreadImport TimedefSayhi (name): Time.sleep (2)    Print('%s Say hello'%name)if __name__=='__main__': T=thread (target=sayhi,args= ('Egon',)) T.start () T.join ( )Print('Main Thread')    Print(T.is_alive ())" "Egon say hello main thread False" "Copy Code

Daemon Thread:

Whether it is a process or a thread, is: Guardian xxx will wait for the main xxx is destroyed after completion,

The main process and main thread under what circumstances will be run complete

1. The main process has finished running at the end of its code (the daemon is recycled at this point). The main process will always wait for non-daemon child processes to run to reclaim the resources of the child process (otherwise it will produce a zombie process) before it ends

2. The main thread runs after the other non-daemon threads have finished running (the daemon thread is recycled at this point). The end of the main thread means the end of the process, and the entire resource of the process is recycled, so the main thread must finish running after the remaining non-daemons are finished

 fromThreadingImportThreadImport TimedefSayhi (name): Time.sleep (2)    Print('%s Say hello'%name)if __name__=='__main__': T=thread (target=sayhi,args= ('Egon',)) T.setdaemon (True)#must be set before T.start ()T.start ()Print('Main Thread')    Print(T.is_alive ())" "Main thread True
Eight-sync lock
three points to note: # 1. Analysis lock must also be explained: The thread Rob is the Gil Lock, get the execution permission to get the mutex lock lock # 2. The difference between using join and locking: Join is waiting for all, that is, the whole serial, while the lock is just a part of the serial # 3. Be sure to look at the final analysis of Gil and mutex in this section

GIL VS Lock

The witty classmate may ask this question, that is, since you said before, Python already has a Gil to ensure that only one thread can execute at the same time, why do we need lock here?

First we need to agree that the purpose of the lock is to protect the shared data, and only one thread at a time can modify the shared data

Then we can conclude that protecting different data should be a different lock.

Finally, the problem is clear, GIL and lock are two locks, the protection of the data is different, the former is the interpreter level (of course, is to protect the interpreter-level data, such as garbage collection data), the latter is to protect the user's own development of the application data, it is obvious that Gil is not responsible for this matter, Only user-defined lock handling, or lock

Process Analysis: All threads rob the Gil lock, or all threads rob the Execute permission

Thread 1 Grab the Gil Lock, get execution permissions, start execution, and then add a lock, not finished, that is, thread 1 has not released lock, it is possible that thread 2 grab the Gil Lock, start execution, the execution of the process found that lock has not been released by thread 1, and then thread 2 into the block, take the execution permissions , it is possible that thread 1 gets the Gil and then normal execution to release lock ... This leads to the effect of serial operation

Since it's serial, we're doing it.

T1.start ()

T1.join

T2.start ()

T2.join ()

This is also serial execution Ah, why add lock, it is necessary to know that the join is waiting for T1 all the code to complete, the equivalent of locking T1 all the code, and lock is only a part of the operation to share data sharing code.

Python concurrent programming Multi-Threading

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.