運行多個線程類似于同時運行多個不同的程序,但具有以下好處 -
一個進程中的多個線程與主線程共享相同的數據空間,因此可以比單獨的進程更容易地共享信息或相互通信。
線程有時稱為輕量級進程,它們不需要太多內存開銷;它們比工藝便宜。
一個線程有一個開始、一個執行順序和一個結束。它有一個指令指針,用于跟蹤它當前在其上下文中運行的位置。
它可以被搶占(中斷)
它可以在其他線程運行時暫時擱置(也稱為休眠) - 這稱為屈服。
開始一個新線程
要生成另一個線程,您需要調用線程模塊中可用的以下方法 -
thread.start_new_thread ( function, args[, kwargs] )
此方法調用支持在 Linux 和 Windows 中快速有效地創建新線程。
方法調用立即返回,子線程啟動并使用傳遞的args列表調用函數。當函數返回時,線程終止。
這里,args是一個參數元組;使用空元組調用函數而不傳遞任何參數。kwargs是關鍵字參數的可選字典。
例子
#!/usr/bin/python
import thread
import time
# Define a function for the thread
def print_time( threadName, delay):
count = 0
while count < 5:
time.sleep(delay)
count += 1
print "%s: %s" % ( threadName, time.ctime(time.time()) )
# Create two threads as follows
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
執行上述代碼時,會產生以下結果 -
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
雖然它對于低級線程非常有效,但是與較新的線程模塊相比,線程模塊非常有限。
線程模塊_
Python 2.4 中包含的較新的線程模塊為線程提供了比上一節中討論的線程模塊更強大、更高級的支持。
threading模塊公開了thread模塊的所有方法并提供了一些額外的方法 -
threading.activeCount() - 返回活動線程對象的數量。
threading.currentThread() - 返回調用者線程控制中線程對象的數量。
threading.enumerate() - 返回當前活動的所有線程對象的列表。
除了方法之外,threading 模塊還有實現線程的Thread類。Thread類提供的方法如下 -
run() - run() 方法是線程的入口點。
start() - start() 方法通過調用 run 方法啟動線程。
join([time]) - join() 等待線程終止。
isAlive() - isAlive() 方法檢查線程是否仍在執行。
getName() - getName() 方法返回線程的名稱。
setName() - setName() 方法設置線程的名稱。
使用線程模塊創建線程
要使用 threading 模塊實現新線程,您必須執行以下操作 -
定義Thread類的新子類。
覆蓋__init__(self [,args])方法以添加其他參數。
然后,重寫 run(self [,args]) 方法來實現線程在啟動時應該做什么。
一旦你創建了新的Thread子類,你就可以創建它的一個實例,然后通過調用start()來啟動一個新線程,然后調用run()方法。
例子
#!/usr/bin/python
import threading
import time
exitFlag = 0
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
print_time(self.name, 5, self.counter)
print "Exiting " + self.name
def print_time(threadName, counter, delay):
while counter:
if exitFlag:
threadName.exit()
time.sleep(delay)
print "%s: %s" % (threadName, time.ctime(time.time()))
counter -= 1
# Create new threads
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)
# Start new Threads
thread1.start()
thread2.start()
print "Exiting Main Thread"
執行上述代碼時,會產生以下結果 -
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
同步線程
Python 提供的線程模塊包括一個易于實現的鎖定機制,允許您同步線程。通過調用Lock()方法創建一個新鎖,該方法返回新鎖。
新鎖對象的acquire(blocking)方法用于強制線程同步運行??蛇x的阻塞參數使您能夠控制線程是否等待獲取鎖。
如果阻塞設置為 0,則如果無法獲取鎖,則線程立即返回 0 值,如果獲取了鎖,則返回 1。如果blocking設置為1,線程阻塞并等待鎖被釋放。
新鎖對象的release()方法用于在不再需要鎖時釋放鎖。
例子
#!/usr/bin/python
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
# Get lock to synchronize threads
threadLock.acquire()
print_time(self.name, self.counter, 3)
# Free lock to release next thread
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 = []
# Create new threads
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)
# Start new Threads
thread1.start()
thread2.start()
# Add threads to thread list
threads.append(thread1)
threads.append(thread2)
# Wait for all threads to complete
for t in threads:
t.join()
print "Exiting Main Thread"
執行上述代碼時,會產生以下結果 -
Starting Thread-1
Starting Thread-2
Thread-1: Thu Mar 21 09:11:28 2013
Thread-1: Thu Mar 21 09:11:29 2013
Thread-1: Thu Mar 21 09:11:30 2013
Thread-2: Thu Mar 21 09:11:32 2013
Thread-2: Thu Mar 21 09:11:34 2013
Thread-2: Thu Mar 21 09:11:36 2013
Exiting Main Thread
多線程優先隊列
Queue模塊允許您創建一個新的隊列對象,該對象可以容納特定數量的項目。有以下方法來控制隊列 -
get() - get() 從隊列中刪除并返回一個項目。
put() - put 將項目添加到隊列中。
qsize() - qsize() 返回當前隊列中的項目數。
empty() - 如果隊列為空,則 empty() 返回 True;否則為假。
full() - 如果隊列已滿,則 full() 返回 True;否則為假。
例子
#!/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()
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
# Create new threads
for tName in threadList:
thread = myThread(threadID, tName, workQueue)
thread.start()
threads.append(thread)
threadID += 1
# Fill the queue
queueLock.acquire()
for word in nameList:
workQueue.put(word)
queueLock.release()
# Wait for queue to empty
while not workQueue.empty():
pass
# Notify threads it's time to exit
exitFlag = 1
# Wait for all threads to complete
for t in threads:
t.join()
print "Exiting Main Thread"
執行上述代碼時,會產生以下結果 -
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