Multiple threads simultaneously executed is similar to a number of different programs, multithreaded operation has the following advantages:
- Using threads can occupy long program in the task into the background to deal with.
- The user interface may be more attractive, so for example the user clicks a button to trigger some event handling, you can pop a progress bar to show the progress of the process
- Running speed could accelerate
- On realized some tasks, such as waiting for user input, document literacy and network to send and receive data, the thread is more useful. In this case, we can free up some valuable resources, such as memory usage and so on.
Threads in the implementation process and the process is different. Each has a separate thread running entry, exit sequence and procedures for the implementation of the order. But the thread is not able to perform independently, it must exist according to the application, providing multiple execution threads controlled by the application.
Each thread has his own set of CPU registers, called the context of the thread, the thread context reflects the last run of the thread CPU register state.
Instruction pointer and stack pointer registers are the two most important thread context registers, the thread always gets run in the context of the process, these addresses are used to mark the process that owns the thread of memory address space.
- Thread can be preempted (interrupted).
- In other threads are running, the thread can be held in abeyance (also known as sleep) - this is the thread of concessions.
Start learning Python threads
Python threads used in two ways: with a function or class to wrap the thread object.
Functional: calling thread module start_new_thread () function to generate a new thread. The syntax is as follows:
thread.start_new_thread ( function, args[, kwargs] )
- function - thread function.
- args - the thread parameters passed to the function, he must be a tuple type.
- kwargs - Optional.
#!/usr/bin/python # -*- coding: UTF-8 -*- import thread import time # 为线程定义一个函数 def print_time( threadName, delay): count = 0 while count < 5: time.sleep(delay) count += 1 print "%s: %s" % ( threadName, time.ctime(time.time()) ) # 创建两个线程 try: thread.start_new_thread( print_time, ("Thread-1", 2, ) ) thread.start_new_thread( print_time, ("Thread-2", 4, ) ) except: print "Error: unable to start thread" while 1: pass
The above program output results are as follows:
Thread-1: Thu Jan 22 15:42:17 2009 Thread-1: Thu Jan 22 15:42:19 2009 Thread-2: Thu Jan 22 15:42:19 2009 Thread-1: Thu Jan 22 15:42:21 2009 Thread-2: Thu Jan 22 15:42:23 2009 Thread-1: Thu Jan 22 15:42:23 2009 Thread-1: Thu Jan 22 15:42:25 2009 Thread-2: Thu Jan 22 15:42:27 2009 Thread-2: Thu Jan 22 15:42:31 2009 Thread-2: Thu Jan 22 15:42:35 2009
The end of the thread is generally rely on the natural end of the thread function; also can call thread.exit thread function (), he throws SystemExit exception, achieve the purpose of exiting thread.
Python provides support for threading through two standard libraries thread and threading. thread provides a low-level, the original thread and a simple lock.
Other methods thread module provides:
- threading.currentThread (): Returns the current thread variable.
- threading.enumerate (): Returns a running thread list contains. Refers running thread started before the end, it does not include the thread before starting and after the termination.
- threading.activeCount (): Returns the number of threads that are running, and len (threading.enumerate ()) have the same result.
In addition to the use of methods, threading module also provides a Thread class to handle the thread, Thread class provides the following methods:
- run (): to indicate the method of active threads.
- start (): start thread activity.
- join ([time]): Wait until the thread is aborted.This blocks the calling thread until the thread's join () method is called suspension - normal exit or throw an unhandled exception - or optional timeout occurs.
- isAlive (): Returns the thread is active.
- getName (): Returns the thread name.
- setName (): Set the thread name.
Use Threading Module to create threads
Use Threading module to create a thread, directly inherited from threading.Thread, then override __init__ method and run methods:
#!/usr/bin/python # -*- coding: UTF-8 -*- import threading import time exitFlag = 0 class myThread (threading.Thread): #继承父类threading.Thread def __init__(self, threadID, name, counter): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.counter = counter def run(self): #把要执行的代码写到run函数里面 线程在创建后会直接运行run函数 print "Starting " + self.name print_time(self.name, self.counter, 5) print "Exiting " + self.name def print_time(threadName, delay, counter): while counter: if exitFlag: thread.exit() time.sleep(delay) print "%s: %s" % (threadName, time.ctime(time.time())) counter -= 1 # 创建新线程 thread1 = myThread(1, "Thread-1", 1) thread2 = myThread(2, "Thread-2", 2) # 开启线程 thread1.start() thread2.start() print "Exiting Main Thread"
The above program execution results are as follows;
Starting Thread-1 Starting Thread-2 Exiting Main Thread Thread-1: Thu Mar 21 09:10:03 2013 Thread-1: Thu Mar 21 09:10:04 2013 Thread-2: Thu Mar 21 09:10:04 2013 Thread-1: Thu Mar 21 09:10:05 2013 Thread-1: Thu Mar 21 09:10:06 2013 Thread-2: Thu Mar 21 09:10:06 2013 Thread-1: Thu Mar 21 09:10:07 2013 Exiting Thread-1 Thread-2: Thu Mar 21 09:10:08 2013 Thread-2: Thu Mar 21 09:10:10 2013 Thread-2: Thu Mar 21 09:10:12 2013 Exiting Thread-2
If multiple threads of a common data modification, unpredictable results might occur, in order to ensure the accuracy of the data, we need to synchronize multiple threads.
Thread object using the Lock and Rlock can achieve a simple thread synchronization, the two objects have methods acquire and release methods, for those who need each allowing only one thread operating data, it can be placed in operation acquire and release methods of the between. as follows:
Multithreading advantage is that it can simultaneously run multiple tasks (at least feels like this). But when threads need to share data, there may be no data synchronization issues.
Consider a case: a list of all elements are zero, the thread "set" from back to front all the elements into one, and the thread "print" from front to back in charge of reading the list and print.
Then, the thread may be "set" began to change when the thread "print" it to print a list, it would be half the output of half a 0, which is the data is not synchronized. To avoid this situation, we introduce the concept of the lock.
Lock has two states - locked and unlocked. Whenever a thread such as "set" to access the shared data, you must first obtain the lock; if you already have another thread, such as "print" to get locked up, then let the thread "set" pause, which is synchronous blocking; wait until the thread " print "access is completed, after the release of the lock, let the thread" set "to continue.
After this process, when you print a list of all output either 0 or 1 full output, no longer appears half embarrassment 0 1 half.
#!/usr/bin/python # -*- coding: UTF-8 -*- import threading import time class myThread (threading.Thread): def __init__(self, threadID, name, counter): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.counter = counter def run(self): print "Starting " + self.name # 获得锁，成功获得锁定后返回True # 可选的timeout参数不填时将一直阻塞直到获得锁定 # 否则超时后将返回False threadLock.acquire() print_time(self.name, self.counter, 3) # 释放锁 threadLock.release() def print_time(threadName, delay, counter): while counter: time.sleep(delay) print "%s: %s" % (threadName, time.ctime(time.time())) counter -= 1 threadLock = threading.Lock() threads =  # 创建新线程 thread1 = myThread(1, "Thread-1", 1) thread2 = myThread(2, "Thread-2", 2) # 开启新线程 thread1.start() thread2.start() # 添加线程到线程列表 threads.append(thread1) threads.append(thread2) # 等待所有线程完成 for t in threads: t.join() print "Exiting Main Thread"
Thread priority queue (Queue)
Python's Queue module provides synchronization, thread-safe queue classes, including FIFO (first in first out) queue Queue, LIFO (last in, first out) queue LifoQueue, and priority queue PriorityQueue. These queues are implemented locking primitives can be used directly in multiple threads. You can use the queue to achieve synchronization between threads.
Queue module commonly used methods:
- Queue.qsize () returns the size of the queue
- Queue.empty () if the queue is empty, returns True, False and vice versa
- Queue.full () If the queue is full, return True, False and vice versa
- Corresponding to the size and maxsize Queue.full
- Queue.get ([block [, timeout]]) Gets the queue, timeout waiting time
- Queue.get_nowait () rather Queue.get (False)
- Queue.put (item) write queue, timeout waiting time
- Queue.put_nowait (item) quite Queue.put (item, False)
- Queue.task_done () after the completion of a work, Queue.task_done () function sends a signal to the task has been completed queue
- Queue.join () really means until the queue is empty, then perform other operations
#!/usr/bin/python # -*- coding: UTF-8 -*- import Queue import threading import time exitFlag = 0 class myThread (threading.Thread): def __init__(self, threadID, name, q): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.q = q def run(self): print "Starting " + self.name process_data(self.name, self.q) print "Exiting " + self.name def process_data(threadName, q): while not exitFlag: queueLock.acquire() if not workQueue.empty(): data = q.get() queueLock.release() print "%s processing %s" % (threadName, data) else: queueLock.release() time.sleep(1) threadList = ["Thread-1", "Thread-2", "Thread-3"] nameList = ["One", "Two", "Three", "Four", "Five"] queueLock = threading.Lock() workQueue = Queue.Queue(10) threads =  threadID = 1 # 创建新线程 for tName in threadList: thread = myThread(threadID, tName, workQueue) thread.start() threads.append(thread) threadID += 1 # 填充队列 queueLock.acquire() for word in nameList: workQueue.put(word) queueLock.release() # 等待队列清空 while not workQueue.empty(): pass # 通知线程是时候退出 exitFlag = 1 # 等待所有线程完成 for t in threads: t.join() print "Exiting Main Thread"
The results of the above program:
Starting Thread-1 Starting Thread-2 Starting Thread-3 Thread-1 processing One Thread-2 processing Two Thread-3 processing Three Thread-1 processing Four Thread-2 processing Five Exiting Thread-3 Exiting Thread-1 Exiting Thread-2 Exiting Main Thread