如何在Python中使用線程進(jìn)行編程
在軟件開(kāi)發(fā)中,線程是執(zhí)行流的一種。愛(ài)掏網(wǎng) - it200.com一個(gè)進(jìn)程可以有多個(gè)線程同時(shí)執(zhí)行,每個(gè)線程獨(dú)立執(zhí)行,并且有自己的棧和寄存器等。愛(ài)掏網(wǎng) - it200.com線程是可以并發(fā)執(zhí)行的,每個(gè)線程都是獨(dú)立的,因此可以提高程序的運(yùn)行效率。愛(ài)掏網(wǎng) - it200.com在Python中,線程模塊是一個(gè)重要的組成部分,它為我們提供了多個(gè)線程的支持。愛(ài)掏網(wǎng) - it200.com本文將討論如何使用Python來(lái)實(shí)現(xiàn)線程。愛(ài)掏網(wǎng) - it200.com
在Python中,有兩個(gè)模塊可以用于線程編程,分別為_thread
(低層次模塊)和threading
(高層次模塊)。愛(ài)掏網(wǎng) - it200.com
_thread
模塊提供了多線程編程的基本支持,是一個(gè)低層次模塊。愛(ài)掏網(wǎng) - it200.com使用該模塊,可以創(chuàng)建,啟動(dòng)和終止線程。愛(ài)掏網(wǎng) - it200.com這個(gè)模塊中的方法在Python 3中已經(jīng)更名為_thread
。愛(ài)掏網(wǎng) - it200.com使用該模塊來(lái)進(jìn)行多線程編程,需要?jiǎng)?chuàng)建線程函數(shù)并且調(diào)用start_new_thread
方法。愛(ài)掏網(wǎng) - it200.com
而threading
模塊對(duì)_thread
模塊進(jìn)行了封裝,提供了一個(gè)更加高級(jí)的多線程編程接口。愛(ài)掏網(wǎng) - it200.com最大的不同是,可以創(chuàng)建Thread
對(duì)象并控制線程的狀態(tài)。愛(ài)掏網(wǎng) - it200.com
使用_thread模塊實(shí)現(xiàn)線程
在Python 3以前的版本,我們需要使用_thread
模塊。愛(ài)掏網(wǎng) - it200.com在Python中,每個(gè)線程都是獨(dú)立的,并且有自己獨(dú)立的線程棧。愛(ài)掏網(wǎng) - it200.com我們可以通過(guò)以下代碼來(lái)實(shí)現(xiàn)多線程:
import _thread
import time
import threading
#使用_thread模塊實(shí)現(xiàn)線程
def thread_function(thread_name,delay):
count=0
while(count<5):
time.sleep(delay)
count+=1
print(thread_name+'執(zhí)行,已執(zhí)行'+str(count)+'次')
#開(kāi)啟三個(gè)線程
try:
_thread.start_new_thread(thread_function,('線程1',1))
_thread.start_new_thread(thread_function,('線程2',2))
_thread.start_new_thread(thread_function,('線程3',3))
except Exception as e:
print(e)
#等待所有線程執(zhí)行結(jié)束
while True:
pass
在以上代碼中:
_thread.start_new_thread()
方法用于開(kāi)啟新線程,并執(zhí)行指定的函數(shù);threading.Thread()
類用于創(chuàng)建線程對(duì)象;time.sleep()
方法用于讓線程暫停一段時(shí)間;
當(dāng)執(zhí)行該代碼時(shí),會(huì)啟動(dòng)3個(gè)線程并并行執(zhí)行。愛(ài)掏網(wǎng) - it200.com每個(gè)線程都會(huì)執(zhí)行thread_function
函數(shù),并在指定的時(shí)間間隔內(nèi)打印一行帶有線程名稱和執(zhí)行次數(shù)的語(yǔ)句。愛(ài)掏網(wǎng) - it200.com
需要注意的是,如果我們?cè)?code>try中調(diào)用_thread.start_new_thread
方法時(shí)發(fā)生了異常,我們會(huì)在except
代碼塊中捕獲該異常。愛(ài)掏網(wǎng) - it200.com否則,我們將陷入死循環(huán),因?yàn)闆](méi)有辦法終止線程,直到它們完成。愛(ài)掏網(wǎng) - it200.com
利用threading
模塊實(shí)現(xiàn)線程
threading
模塊比_thread
模塊提供了更加高級(jí)的線程編程接口。愛(ài)掏網(wǎng) - it200.comthreading
模塊提供了Thread
類,可以使用該類來(lái)創(chuàng)建線程對(duì)象并控制線程狀態(tài)。愛(ài)掏網(wǎng) - it200.com下面是使用threading
模塊實(shí)現(xiàn)線程的代碼:
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
self.count = 0
def run(self):
print ("開(kāi)始線程:" + self.name)
while self.count < 5:
time.sleep(self.delay)
self.count += 1
print ("%s執(zhí)行,已執(zhí)行%s次" % (self.name, str(self.count)))
print ("結(jié)束線程:" + self.name)
# 創(chuàng)建線程
thread1 = MyThread(1, "線程1", 1)
thread2 = MyThread(2, "線程2", 2)
thread3 = MyThread(3, "線程3", 3)
# 開(kāi)啟線程
thread1.start()
thread2.start()
thread3.start()
# 等待線程結(jié)束
thread1.join()
thread2.join()
thread3.join()
print ("退出主線程")
在以上代碼中,我們定義了MyThread
類,該類繼承了threading.Thread
類。愛(ài)掏網(wǎng) - it200.com在類中,我們定義了構(gòu)造函數(shù)和run
方法。愛(ài)掏網(wǎng) - it200.com構(gòu)造函數(shù)用于初始化線程對(duì)象,并為線程指定ID、名稱和延遲時(shí)間。愛(ài)掏網(wǎng) - it200.comrun
方法是線程要執(zhí)行的代碼。愛(ài)掏網(wǎng) - it200.com
其中,我們使用了time.sleep()
方法來(lái)讓線程在指定的時(shí)間內(nèi)暫停,并通過(guò)計(jì)數(shù)器來(lái)控制線程的循環(huán)次數(shù)。愛(ài)掏網(wǎng) - it200.com當(dāng)計(jì)數(shù)器達(dá)到5時(shí),線程就會(huì)結(jié)束。愛(ài)掏網(wǎng) - it200.com
在主線程中,我們創(chuàng)建了3個(gè)線程對(duì)象,并通過(guò)調(diào)用start()
方法來(lái)開(kāi)啟線程。愛(ài)掏網(wǎng) - it200.com為了等待線程結(jié)束,我們使用了join()
方法。愛(ài)掏網(wǎng) - it200.com最后,我們?cè)谥骶€程中輸出了一條消息。愛(ài)掏網(wǎng) - it200.com
線程鎖
在線程編程中,由于多個(gè)線程同時(shí)訪問(wèn)共享資源,我們經(jīng)常需要使用線程鎖來(lái)保證線程安全。愛(ài)掏網(wǎng) - it200.comPython提供了_thread
和threading
兩個(gè)模塊的鎖。愛(ài)掏網(wǎng) - it200.com下面是一個(gè)使用threading
模塊的鎖實(shí)例:
import threading
# 共享資源
num = 0
# 創(chuàng)建鎖
lock = threading.Lock()
def add_number():
global num
# 獲取鎖
lock.acquire()
try:
# 修改共享資源
num += 1
finally:
# 釋放鎖
lock.release()
class MyThread(threading.Thread):
def run(self):
for i in range(100000):
add_number()
# 創(chuàng)建線程
thread1 = MyThread()
thread2 = MyThread()
# 開(kāi)啟線程
thread1.start()
thread2.start()
# 等待線程結(jié)束
thread1.join()
thread2.join()
# 輸出結(jié)果
print(num)
在以上代碼中,我們創(chuàng)建了一個(gè)全局變量num
,它將被多個(gè)線程訪問(wèn)。愛(ài)掏網(wǎng) - it200.com我們使用了threading.Lock()
類來(lái)創(chuàng)建一個(gè)鎖對(duì)象。愛(ài)掏網(wǎng) - it200.com
在add_number()
函數(shù)中,我們獲得了鎖對(duì)象,并修改了共享資源num
的值。愛(ài)掏網(wǎng) - it200.com最后,我們釋放了鎖。愛(ài)掏網(wǎng) - it200.com