Before using multithreading, we need to understand what processes and threads are on the homepage. What is a process? Computer programs are only executable binary (or other types) data on disks. They start their life cycle only when they are read to the memory and called by the operating system. A process (sometimes called a heavyweight process) is an execution of a program. Each process has its own address space, memory, data stack, and other auxiliary data that records its running track. The operating system manages all processes running on them and assigns time to these processes fairly. What is a thread? A thread (sometimes called a lightweight process) is similar to a process. The difference is that all threads run in the same process and share the same runtime environment. We can imagine a "Mini process" that runs in parallel in the main process or the "main thread ". 7.2.1 a single thread executes two cycles sequentially in a single thread. You must end one loop before the other can start. The total time is the sum of the running times of each loop. Onetherad. py from time import sleep, ctime def loop0 (): print 'start loop 0 at: ', ctime () sleep (4) print 'loop 0 done at:', ctime () def loop1 (): print 'start loop 1 at: ', ctime () sleep (2) print 'loop 1 done at:', ctime () def main (): print 'start: ', ctime () loop0 () loop1 () print 'all end:', ctime () if _ name _ = '_ main _': running result: start loop 0 at: Mon Dec 23 09:59:44 2013 loop 0 done at: Mon Dec 23 09:59:48 2013 start loop 1 at: Mon Dec 23 09:59:48 2013 loop 1 done at: Mon Dec 23 09:59:50 2013all end: mon Dec 23 09:59:50 2013 Python provides thread support through two standard libraries: thread and threading. Thread provides a low-level, original thread, and a simple lock. Threading is a Java-based thread model design. Lock and Condition variables are the basic behavior of objects in Java (each object has a Lock and Condition variable), while in Python, they are independent objects. 7.2.1. thread module mtsleep1.py import thread from time import sleep, ctime loops = [4, 2] def loop0 (): print 'start loop 0 at: ', ctime () sleep (4) print 'loop 0 done at: ', ctime () def loop1 (): print 'start loop 1 at:', ctime () sleep (2) print 'loop 1 done: ', ctime () def main (): print 'start:', ctime () thread. start_new_thread (loop0, () thread. start_new_thread (loop1, () sleep (6) print 'all end: ', ctime () If _ name _ = '_ main _': main () start_new_thread () must have the first two parameters. Therefore, even if the function we want to run is not a parameter, we need to pass an empty tuples. The output of this program is not the same as that of the previous one. It was run for 6 to 7 seconds, but now it is 4 seconds, is the sum of the running time of the longest loop and the time of other code. Running result: start: Mon Dec 23 10:05:09 2013 start loop 0 at: Mon Dec 23 10:05:09 2013 start loop 1 at: Mon Dec 23 10:05:09 2013 loop 1 done: mon Dec 23 10:05:11 2013 loop 0 done at: Mon Dec 23 10:05:13 2013all end: Mon Dec 23 10:05:15 2013 sleeping 4 s and 2 s code is now executed concurrently. In this way, the total running time is shortened. As you can see, loop1 ends even before loop0. A major difference in the program is that there is an additional "sleep (6)" function call. If we do not stop the main thread, the main thread runs the next statement and displays "all end". Then, the loop0 () and loop1 () and quit. We use 6 seconds because we already know that two threads (you know, one takes 4 seconds and the other takes 2 seconds) should have ended after the main thread waits for 6 seconds. You may be thinking about how to manage threads, rather than performing an additional 6-second operation in the main thread. As a result, our total running time is not less than the version of a single thread. In addition, using the sleep () function for thread synchronization is unreliable. If the execution time of our loop cannot be determined in advance, what should we do? This may cause the main thread to exit too early or too late. This is the application of the lock. Mtsleep2.py # coding = utf-8import thread from time import sleep, ctime loops = [4, 2] def loop (nloop, nsec, lock): print 'start loop ', nloop, 'at :', ctime () sleep (nsec) print 'loop ', nloop, 'done at:', ctime () # unlock lock. release () def main (): print 'starting at: ', ctime () locks = [] # create a list with a loops array, and assigned to nloops = range (len (loops) for I in nloops: lock = thread. allocate_lock () # lock. acquire () # append Locks [] in the array. append (lock) # execute multithreading for I in nloops: thread. start_new_thread (loop, (I, loops [I], locks [I]) for I in nloops: while locks [I]. locked (): pass print 'all end: ', ctime () if _ name _ =' _ main _ ': main () copy the code thread. allocate_lock () returns a new lock object. Acquire ()/release () an original lock has two states: locking and unlocking, corresponding to the acquire () and release () methods respectively. The range () function is used to create a list containing arithmetic series. Range (len (loops) comprehension: copy the code >>> aa = "hello" # length calculation >>> len (aa) 5 # create a list> range (len (aa) [0, 1, 2, 3, 4] # elements of the loop output list >>> for a in range (len (aa): print a we call thread first. the allocate_lock () function creates a lock list and calls the acquire () function of each lock to obtain the lock. "Lock" is obtained ". After the lock, we put the lock in the lock list locks. The next cycle creates a thread. Each thread uses its own cycle number, and the sleep time and lock are used as parameters to call the loop () function. Why don't we create threads in the lock creation loop? There are several reasons: (1) We want to implement thread synchronization, so we need to make "All horses rush out of the fence at the same time ". (2) It takes some time to get the lock. If your thread exits "too fast", it may cause the thread to be finished before the lock is obtained. At the end of the thread, the thread should unlock it by itself. The last loop is just sitting there waiting until the main thread is suspended until the two locks are unlocked. Mtsleep2.py running result: starting at: Mon Dec 23 20:57:26 2013 start loop start loop0 1at: at: Mon Dec 23 20:57:26 2013 Mon Dec 23 20:57:26 2013 loop 1 done: mon Dec 23 20:57:28 2013 loop 0 done at: Mon Dec 23 20:57:30 2013all end: Mon Dec 23 20:57:30 2013 7.2.1 and threading modules we should avoid using the thread module, the reason is that it does not support daemon threads. When the main thread exits, all sub-threads will be forcibly exited, whether or not they are still working. Sometimes we don't expect this kind of behavior, so we introduce the concept of daemon. The threading module supports daemon threads. Mtsleep3.py copy Code # coding = utf-8import threading from time import sleep, ctime loops = [4, 2] def loop (nloop, nsec): print 'start loop ', nloop, 'at :', ctime () sleep (nsec) print 'loop ', nloop, 'done at:', ctime () def main (): print 'starting at: ', ctime () threads = [] nloops = range (len (loops) # create a thread for I in nloops: t = threading. thread (target = loop, args = (I, loops [I]) threads. append (t) # Start thread for I in nl Oops: threads [I]. start () # Wait for All End threads for I in nloops: threads [I]. join () print 'all end: ', ctime () if _ name _ =' _ main _ ': main () running result: starting: mon Dec 23 22:58:55 2013 start loop 0 at: Mon Dec 23 22:58:55 2013 start loop 1 at: Mon Dec 23 22:58:55 2013 loop 1 done at: Mon Dec 23 22:58:57 2013 loop 0 done: mon Dec 23 22:58:59 2013all end: Mon Dec 23 22:58:59 2013 start () starts thread activity join () waiting for the thread to terminate all After the threads are created, call the start () function together to start, instead of creating one to start. In addition, you do not need to manage a bunch of locks (assign locks, obtain locks, release locks, and check the lock status), as long as you can simply call the join () function for each thread. Join () will wait until the thread ends, or when the timeout parameter is given, until the timeout. Another important aspect of join () is that it does not need to be called at all. Once the thread starts, it runs until the function of the thread ends and exits. Use the callable class mtsleep4.py # coding = utf-8import threading from time import sleep, ctime loops = [4, 2] class ThreadFunc (object): def _ init _ (self, func, args, name = ''): self. name = name self. func = func self. args = args def _ call _ (self): apply (self. func, self. args) def loop (nloop, nsec): print "seart loop", nloop, 'at: ', ctime () sleep (nsec) print 'loop', nloop, 'done at: ', ctime () def main (): print 'starting at:', ctime () Threads = [] nloops = range (len (loops) for I in nloops: # Call ThreadFunc to instantiate the object and create all threads t = threading. thread (target = ThreadFunc (loop, (I, loops [I]), loop. _ name _) threads. append (t) # Start thread for I in nloops: threads [I]. start () # Wait for All End threads for I in nloops: threads [I]. join () print 'all end: ', ctime () if _ name _ =' _ main _ ': main () running result: starting: tue Dec 24 16:39:16 2013 seart loop 0 at: Tue Dec 24 16: 39: 16 2013 seart loop 1 at: Tue Dec 24 16:39:16 2013 loop 1 done at: Tue Dec 24 16:39:18 2013 loop 0 done at: Tue Dec 24 16:39:20 2013all end: when Tue Dec 24 16:39:20 2013 creates a new Thread, the Thread object will call our ThreadFunc object, and a special function _ call _ () will be used __(). Because we already have parameters to use, we do not need to upload them to the constructor of Thread. Since we have a parameter tuples, we need to use the apply () function in the code. We passed a callable class (Instance) instead of just passing a function. The _ init _ () method runs when an object of the class is created. This method can be used to initialize your object. The apply () apply (func [, args [, kwargs]) function is used to call a function indirectly when a function parameter already exists in a tuple or dictionary. Args is a tuple that contains parameters that will be provided to the function by location. If args is omitted, no parameters will be passed. kwargs is a dictionary containing key parameters. # Methods without parameters >>> def say (): print 'say in' >>> apply (say) say in # The function only includes the parameter >>> def say (a, B): print a, B >>> apply (say, ('hello ', 'passer') hello passer' # function with keyword parameter >>> def say (a = 1, B = 2): print, B >>> def haha (** kw): apply (say, (), kw) >>> haha (a = 'A', B = 'B') a B