Transferred from: http://www.cnblogs.com/fnng/p/3489321.html
Before using multithreading, we need to understand what processes and threads are in the home page.
What is a process?
A computer program is simply an executable, binary (or other type) of data on a disk. They only start their lifetimes when they are read into memory and are called by the operating system. A process (sometimes called a heavyweight process) is a single execution of a program. Each process has its own address space, memory, data stack, and other auxiliary data that records its running trajectory. The operating system manages all the processes running on it and distributes the time fairly for those processes.
What is a thread?
Threads (sometimes referred to as lightweight processes) are somewhat similar to processes, but all threads run in the same process and share the same running environment. We can imagine it as a "mini-process" running in parallel in the main process or "main thread".
7.2.1, Single thread
Executes two loops sequentially in a single thread. Make sure that one cycle ends and another can begin. The total time is the sum of each cycle running time.
onetherad.py
From time import sleep, CTime def loop0 (): print ' start loop 0 at: ', CTime () sleep (4) print ' Loop 0 did at: ', CTime () def loop1 (): print ' Start loop 1 at: ', CTime () sleep (2) print ' Loop 1 do at: ', CTime () def Main (): print ' Start: ', CTime () loop0 () loop1 () print ' All end: ', CTime () if __name__ = = ' __ MAIN__ ': Main ()
Operation Result:
Start loop 0 At:mon Dec 09:59:44 2013loop 0 done At:mon Dec 09:59:48 2013start Loop 1 At:mon Dec 23 09:59:48 2013 Loop 1 done At:mon Dec 09:59:50 2013all End:mon Dec 23 09:59:50 2013
Python provides support for threads through the two standard library thread and threading. The thread provides a low-level, primitive thread, and a simple lock. Threading Java-based threading model design. Lock and condition variables (Condition) are the basic behavior of objects in Java (each object has its own lock and condition variable), whereas in Python it is a separate object.
7.2.1, Thread module
mtsleep1.py
Import thread from time to import sleep, ctime loops = [4,2]def loop0 (): print ' start loop 0 at: ', CTime () sleep (4)
print ' Loop 0 done on: ', CTime () def loop1 (): print ' Start loop 1 at: ', CTime () sleep (2) print ' Loop 1 Done at: ', 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__ ':
Start_new_thread () requirements must have the first two parameters. So, even if the function we want to run doesn't have arguments, we're going to pass an empty tuple.
The output of this program is very different from the previous output, before it was run 6, 7 seconds, and now is 4 seconds, is the longest cycle of running time with other code time sum.
Operation Result:
Start:mon Dec 10:05:09 2013start Loop 0 At:mon Dec 10:05:09 2013start Loop 1 At:mon Dec 10:05:09 2013loop 1 Do Ne at:mon Dec 10:05:11 2013loop 0 done At:mon Dec 10:05:13 2013all End:mon Dec 23 10:05:15 2013
The code that sleeps 4 seconds and 2 seconds is now executed concurrently. This makes the overall run time shortened. As you can see, loop1 even ends up in front of loop0.
One of the big differences in the program is a function call that has a "sleep (6)". If we do not make the main thread stop, the main thread will run the next statement, show "All End", and then close the two threads running Loop0 () and LOOP1 () and exit. We use 6 seconds because we already know that two threads (you know, one to 4 seconds and one to 2 seconds) should be over after the main thread waits 6 seconds.
You might be wondering what good way to manage threads instead of doing an extra 6-second delay in the main thread. Because of this, our total run time is no less than a single-threaded version. Also, it is unreliable to use the sleep () function as a synchronous operation for threads like this. What if the execution time of our cycle cannot be determined beforehand? This can cause the main thread to exit prematurely or late. This is where the lock comes in.
mtsleep2.py
#coding =utf-8import thread from time import sleep, ctime loops = [4,2] def loop (Nloop, Nsec, lock): print ' sta RT Loop ', Nloop, ' at: ', CTime () sleep (nsec) print ' Loop ', Nloop, ' do at: ', CTime () #解锁 lock.release () def main (): print ' starting at: ', CTime () locks =[] #以loops数组创建列表, and assign to nloops Nloops = Range ( Len (loops)) for i in Nloops: lock = Thread.allocate_lock () #锁定 lock.acquire () #追加到locks [] An array of locks.append (lock) #执行多线程 for i in Nloops: Thread.start_new_thread (Loop, (i,loops[i],locks [i])) For I in Nloops: when locks[i].locked (): pass print ' All end: ', CTime () if __name__ = = ' __main__ ': m Ain ()
Thread.allocate_lock ()
Returns a new lock object.
Acquire ()/release ()
A primitive lock has two states, locking and unlocking, corresponding to the acquire () and release () methods.
Range ()
The range () function creates a list that contains arithmetic progression.
Range (len (loops)) understands:
>>> aa= "Hello" #长度计算 >>> len (aa) AA to create a list >>> range (len (aa)) [0, 1, 2, 3, 4] #循环输出列表元素 >>> For a in range (len (aa)): print a 01234
We first call the Thread.allocate_lock () function to create a list of locks and call each lock's acquire () function to get the lock. Obtaining a lock means "locking the lock". When locked, we put the lock in the lock list locks.
The next loop creates the thread, and each thread calls the loop () function with its own loop number, sleep time, and lock parameters. Why don't we create a thread in the loop that creates the lock? There are several reasons for this: (1) We want to synchronize the threads so that "all horses are out of the fence at the same time." (2) It takes some time to get a lock, and if your thread exits "too fast", it may cause the thread to end without getting the lock.
At the end of the thread, the threads have to do their own unlocking operations. The last loop is just sitting there waiting (for the purpose of pausing the main thread) until two locks are unlocked before they continue to run.
mtsleep2.py Running results:
Starting At:mon Dec 20:57:26 2013start loop start loop0 1at: at:mon Dec 20:57:26 Mon Dec 23 20:57:26 2 013loop 1 done At:mon Dec 20:57:28 2013loop 0 done At:mon Dec 20:57:30 2013all End:mon Dec 23 20:57:30 2013
7.2.1, Threading Module
We should avoid using the thread module because it does not support the daemon thread. When the main thread exits, all child threads are forced to quit, regardless of whether they are still working. Sometimes we don't expect this behavior, and then we introduce the concept of the daemon thread. The threading module supports the daemon thread.
mtsleep3.py
#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, ' do at: ', CTime () def main (): print ' sta Rting at: ', CTime () threads = [] nloops = range (len (loops)) #创建线程 for i in nloops: t = Threading. Thread (target=loop,args= (I,loops[i])) threads.append (t) #开始线程 for i in Nloops: threads[i]. Start () #等待所有结束线程 for i in Nloops: threads[i].join () print ' All end: ', CTime () if __name__ = = ' __ MAIN__ ': Main ()
Operation Result:
Starting At:mon Dec 22:58:55 2013start Loop 0 At:mon Dec 22:58:55 2013start Loop 1 at:mon Dec 22:58:55 2013loo P 1 done at:mon Dec 22:58:57 2013loop 0 done At:mon Dec 22:58:59 2013all End:mon Dec 23 22:58:59 2013
Start ()
Start thread activity
Join ()
Waiting for thread to terminate
After all the threads have been created, call the start () function together to start, instead of creating a startup one. And, instead of managing a bunch of locks (assigning locks, acquiring locks, releasing locks, checking the state of locks, etc.), simply call the join () function on each thread.
Join () waits until the thread ends, or when the timeout parameter is given, until the timeout is reached. Another important aspect of join () is that it can not be called at all. Once the thread is started, it runs until the thread's function 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 in: ', CTime () def main (): print ' starting at: ', CTime () threads=[] nloops = Range (len (loops)) for I in Nloops: #调用ThreadFunc实例化的对象, create all threads T = Threading. Thread ( Target=threadfunc (Loop, (i,loops[i)), loop.__name__)) threads.append (t) #开始线程 for i in Nloops: threads[i].start () #等待所有结束线程 for i in Nloops: threads[i].join () print ' All end: ', CTime () if __name__ = = ' __main__ ': Main ()
Operation Result:
Starting At:tue Dec 16:39:16 2013seart Loop 0 at:tue Dec 16:39:16 2013seart Loop 1 at:tue Dec 16:39:16 2013loo P 1 done at:tue Dec 16:39:18 2013loop 0 done at:tue Dec 16:39:20 2013all end:tue Dec 24 16:39:20 2013
When a new thread is created, the thread object calls our ThreadFunc object, and a special function __call__ () is used. Since we already have the parameters to use, we don't have to go into the constructor of Thread (). Since we have a tuple of parameters, we want to use the Apply () function in the code.
Instead of just passing a function, we passed a callable class (the instance).
__init__ ()
Method runs when an object of the class is built. This method can be used to initialize some of your objects.
Apply ()
The Apply (func [, args [, Kwargs]]) function is used to indirectly invoke a function when a function parameter already exists in a tuple or dictionary. Args is a tuple that contains the arguments passed by position that will be supplied to the function. If args is omitted, no arguments are passed, and Kwargs is a dictionary containing the keyword arguments.
Apply () Usage:
#不带参数的方法 >>> def Say (): print ' say in ' >>> apply (say) say in# function only with tuple parameters >>> def say (A, B): Print a,b>>> Apply (say, (' Hello ', ' Zerg ')) Hello worm # function with keyword parameter >>> def say (a=1,b=2): Print A, b >>> def haha (**kw): apply (say, (), kw) >>> haha (a= ' a ', b= ' B ') a B
Python Multithreading Concepts