多線程類似于同時(shí)執(zhí)行多個(gè)不同程序蹲坷,多線程運(yùn)行有如下優(yōu)點(diǎn):
- 使用線程可以把占據(jù)長(zhǎng)時(shí)間的程序中的任務(wù)放到后臺(tái)去處理。
- 用戶界面可以更加吸引人级乐,比如用戶點(diǎn)擊了一個(gè)按鈕去觸發(fā)某些事件的處理风科,可以彈出一個(gè)進(jìn)度條來顯示處理的進(jìn)度
- 程序的運(yùn)行速度可能加快
- 在一些等待的任務(wù)實(shí)現(xiàn)上如用戶輸入、文件讀寫和網(wǎng)絡(luò)收發(fā)數(shù)據(jù)等题山,線程就比較有用了故痊。在這種情況下我們可以釋放一些珍貴的資源如內(nèi)存占用等等。
- 線程在執(zhí)行過程中與進(jìn)程還是有區(qū)別的慨菱。每個(gè)獨(dú)立的線程有一個(gè)程序運(yùn)行的入口抡柿、順序執(zhí)行序列和程序的出口等恐。但是線程不能夠獨(dú)立執(zhí)行课蔬,必須依存在應(yīng)用程序中,由應(yīng)用程序提供多個(gè)線程執(zhí)行控制战惊。
應(yīng)用
Python3 線程中常用的兩個(gè)模塊為:
- _thread
- threading(推薦使用)
??thread 模塊已被廢棄吞获。用戶可以使用 threading 模塊代替谚鄙。所以,在 Python3 中不能再使用"thread" 模塊烤黍。為了兼容性傻盟,Python3 將 thread 重命名為 "_thread"。
Python中使用線程有兩種方式:函數(shù)或者用類來包裝線程對(duì)象规哲。
函數(shù)式:調(diào)用 _thread 模塊中的start_new_thread()函數(shù)來產(chǎn)生新線程媳叨。語法如下:
_thread.start_new_thread ( function, args[, kwargs] )
參數(shù)說明:
- function - 線程函數(shù)。
- args - 傳遞給線程函數(shù)的參數(shù),他必須是個(gè)tuple類型糊秆。
- kwargs - 可選參數(shù)痘番。
#!/usr/bin/python3
import _thread
import time
# 為線程定義一個(gè)函數(shù)
def print_time( threadName, delay):
count = 0
while count < 5:
time.sleep(delay)
count += 1
print ("%s: %s" % ( threadName, time.ctime(time.time()) ))
# 創(chuàng)建兩個(gè)線程
try:
_thread.start_new_thread( print_time, ("Thread-1", 2, ) )
_thread.start_new_thread( print_time, ("Thread-2", 4, ) )
except:
print ("Error: 無法啟動(dòng)線程")
while 1:
pass
#輸出
Thread-1: Wed Apr 6 11:36:31 2016
Thread-1: Wed Apr 6 11:36:33 2016
Thread-2: Wed Apr 6 11:36:33 2016
Thread-1: Wed Apr 6 11:36:35 2016
Thread-1: Wed Apr 6 11:36:37 2016
Thread-2: Wed Apr 6 11:36:37 2016
Thread-1: Wed Apr 6 11:36:39 2016
Thread-2: Wed Apr 6 11:36:41 2016
Thread-2: Wed Apr 6 11:36:45 2016
Thread-2: Wed Apr 6 11:36:49 2016
案例
簡(jiǎn)單的應(yīng)用了解了我們實(shí)際練習(xí)一下簡(jiǎn)單案例
- 用多線程構(gòu)造新的列表汞舱,將每個(gè)元素做平方計(jì)算
注意:
- 線程設(shè)置中的put和get的作用和用法
- 參數(shù)設(shè)置方法
- 線程列表添加
import threading
import time
from queue import Queue
def job(l, q):
for i in range(len(l)):
l[i] = l[i]**2
q.put(l) #將數(shù)據(jù)推送到隊(duì)列昂芜,多線程不支持返回值
def main():
q = Queue()
threads = []
results = []
data = [[1, 2, 3], [3, 4, 5], [4, 4, 4], [5, 5, 5]]
for i in range(4):
t = threading.Thread(target=job, args=(data[i], q)) #創(chuàng)建線程泌神,可用args傳入?yún)?shù)舞虱,記得傳入隊(duì)列
t.start()
threads.append(t) #將每個(gè)線程加入到線程列表
for thread in threads:
thread.join() #將線程加入到主線程
for _ in range(4):
results.append(q.get()) #獲取隊(duì)列里面的列表數(shù)據(jù)
print(results)
if __name__ == '__main__':
main()
- 計(jì)算列表元素sum值,為了體現(xiàn)多線程的速度優(yōu)勢(shì)损趋,我們?cè)O(shè)置time函數(shù)展示
import threading
from queue import Queue
import time
import copy
def job(l, q):
res = sum(l)
q.put(res)
def multithreading(l):
q = Queue()
threads = []
for i in range(4):
t = threading.Thread(target=job, args=(copy.copy(l), q), name='T%i' %i)
t.start()
threads.append(t)
for thread in threads:
t.join()
total = 0
for _ in range(4):
total += q.get()
print(total)
def normal(l):
total = sum(l)
print(total)
if __name__ == '__main__':
l = list(range(1000000))
s_t = time.time()
normal(l*4)
print('normal: ', time.time() - s_t)
s_t = time.time()
multithreading(l)
print('multithreading: ', time.time() - s_t)