多線程類似於同時執行多個不同程序,多線程運行有如下優點:
- 使用線程可以把佔據長時間的程序中的任務放到後臺去處理。
- 用戶界面可以更加吸引人,比如用戶點擊了一個按鈕去觸發某些事件的處理,可以彈出一個進度條來顯示處理的進度
- 程序的運行速度可能加快
- 在一些等待的任務實現上如用戶輸入、文件讀寫和網絡收發數據等,線程就比較有用了。在這種情況下我們可以釋放一些珍貴的資源如內存佔用等等。
- 線程在執行過程中與進程還是有區別的。每個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口。但是線程不能夠獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。
應用
Python3 線程中常用的兩個模塊爲:
- _thread
- threading(推薦使用)
thread 模塊已被廢棄。用戶可以使用 threading 模塊代替。所以,在 Python3 中不能再使用"thread" 模塊。爲了兼容性,Python3 將 thread 重命名爲 "_thread"。
Python中使用線程有兩種方式:函數或者用類來包裝線程對象。
函數式:調用 _thread 模塊中的start_new_thread()函數來產生新線程。語法如下:
_thread.start_new_thread ( function, args[, kwargs] )
參數說明:
- function - 線程函數。
- args - 傳遞給線程函數的參數,他必須是個tuple類型。
- kwargs - 可選參數。
#!/usr/bin/python3
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: 無法啓動線程")
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
案例
簡單的應用瞭解了我們實際練習一下簡單案例
- 用多線程構造新的列表,將每個元素做平方計算
注意:
- 線程設置中的put和get的作用和用法
- 參數設置方法
- 線程列表添加
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) #將數據推送到隊列,多線程不支持返回值
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)) #創建線程,可用args傳入參數,記得傳入隊列
t.start()
threads.append(t) #將每個線程加入到線程列表
for thread in threads:
thread.join() #將線程加入到主線程
for _ in range(4):
results.append(q.get()) #獲取隊列裏面的列表數據
print(results)
if __name__ == '__main__':
main()
- 計算列表元素sum值,爲了體現多線程的速度優勢,我們設置time函數展示
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)