线程是操作系统调度的最小单元,线程通常通过fork()来创建。线程通常存在在进程中,一个进程可以有多个线程。这些线程共享进程的内存和状态。
线程的处理比进程简单,所以线程有称为轻量级进程。
有两种线程:
- 内核线程,是操作系统的一部分。
- 用户空间线程或用户线程,不在内核中执行。
线程的好处有:
- 在多CPU的环境下,多线程是并发执行的,程序运行更加快速。而且线程需要的内存开销比进程小。
- 多个线程是共享全局变量的。线程之间共享主线程的全局变量,线程之间的通信更加容易。
threading模块的主要方法
- threading.activeCount(),返回状态为active的线程数量
- threading.currentThread(),返回调用者控制的线程数量
- threading.enumerate(),返回当前活跃的线程列表
- run(), 线程入口
- start(),启动一个线程,并调用其run方法
- join([time]),等待线程终止
- isAlive(),判断线程是否在执行
- getName(),返回线程名称
- setName(),设置线程名称
创建线程
- 定义threading.Thread的子类
- 重载__init__(self [,args])方法
- 重载run(self [, args])方法来完成线程真正要做的事情
#!/usr/bin/python
import threading
import time
exitFlag = 0
class myThread(threading.Thread): #继承父类threading.Thread
def __init__(self, threadID, name, delay): ##重载__init__方法
threading.Thread.__init__(self) ##复用父类的__init__方法
self.threadID = threadID
self.name = name
self.delay = delay
def run(self): ##重载run方法,这是线程真正要做的事情
print "Starting " + self.name
print_time(self.name, self.delay, 3)
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"
程序运行结果为:
Starting thread-1Starting thread-2
Exiting Main Thread
thread-1: Fri Apr 17 15:27:20 2015
thread-2: Fri Apr 17 15:27:21 2015
thread-1: Fri Apr 17 15:27:21 2015
thread-1: Fri Apr 17 15:27:22 2015
Exiting thread-1
thread-2: Fri Apr 17 15:27:23 2015
thread-2: Fri Apr 17 15:27:25 2015
Exiting thread-2
Exiting Main Thread
thread-1: Fri Apr 17 15:27:20 2015
thread-2: Fri Apr 17 15:27:21 2015
thread-1: Fri Apr 17 15:27:21 2015
thread-1: Fri Apr 17 15:27:22 2015
Exiting thread-1
thread-2: Fri Apr 17 15:27:23 2015
thread-2: Fri Apr 17 15:27:25 2015
Exiting thread-2
线程同步
threading模块提供了锁机制进行线程之间的同步。用Lock()方法创建一个锁,用acquire(blocking)方法来强制线程同步运行,release()方法来释放锁。
代码实例:
#!/usr/bin/python
import threading
import time
class myThread(threading.Thread):
def __init__(self, threadID, name, delay):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.delay = delay
def run(self):
print "Starting " + self.name
threadLock.acquire()
print_time(self.name, self.delay, 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, "thread1", 1)
thread2 = myThread(2, "thread2", 2)
thread1.start()
thread2.start()
threads.append(thread1)
threads.append(thread2)
for t in threads:
t.join()
print "Exiting Main Thread"
程序运行结果为:
Starting thread1
Starting thread2
thread1 : Fri Apr 17 16:00:15 2015
thread1 : Fri Apr 17 16:00:16 2015
thread1 : Fri Apr 17 16:00:17 2015
thread2 : Fri Apr 17 16:00:19 2015
thread2 : Fri Apr 17 16:00:21 2015
thread2 : Fri Apr 17 16:00:23 2015
Exiting Main Thread
Starting thread2
thread1 : Fri Apr 17 16:00:15 2015
thread1 : Fri Apr 17 16:00:16 2015
thread1 : Fri Apr 17 16:00:17 2015
thread2 : Fri Apr 17 16:00:19 2015
thread2 : Fri Apr 17 16:00:21 2015
thread2 : Fri Apr 17 16:00:23 2015
Exiting Main Thread
多线程的优先级队列
Queue模块允许创建一个队列,Queue中的主要方法有:
- get(),从队列中获取一个元素,并将该元素从队列中删除
- put(),向队列中添加一个元素
- qsize(),返回该队列中元素数目
- empty(),如果该队列是空,返回True;否则返回False
- full(),如果该队列满,则返回True;否则返回False
#!/usr/bin/python
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()
pritn "%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"
代码执行结果为:
Starting Thread-1Starting Thread-2
Starting Thread-3
Thread-3 processing One
Thread-2 processing Two
Thread-1 processing Three
Thread-2 processing Four
Thread-3 processing Five
Exiting Thread-1
Exiting Thread-3
Exiting Thread-2
Exiting Main Thread
Starting Thread-3
Thread-3 processing One
Thread-2 processing Two
Thread-1 processing Three
Thread-2 processing Four
Thread-3 processing Five
Exiting Thread-1
Exiting Thread-3
Exiting Thread-2
Exiting Main Thread