多線程

多線程類似於同時執行多個不同程序,多線程運行有如下優點:

  1. 使用線程可以把佔據長時間的程序中的任務放到後臺去處理。
  2. 用戶界面可以更加吸引人,比如用戶點擊了一個按鈕去觸發某些事件的處理,可以彈出一個進度條來顯示處理的進度
  3. 程序的運行速度可能加快
  4. 在一些等待的任務實現上如用戶輸入、文件讀寫和網絡收發數據等,線程就比較有用了。在這種情況下我們可以釋放一些珍貴的資源如內存佔用等等。
  5. 線程在執行過程中與進程還是有區別的。每個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口。但是線程不能夠獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。

應用

Python3 線程中常用的兩個模塊爲:

  1. _thread
  2. threading(推薦使用)
      thread 模塊已被廢棄。用戶可以使用 threading 模塊代替。所以,在 Python3 中不能再使用"thread" 模塊。爲了兼容性,Python3 將 thread 重命名爲 "_thread"。

Python中使用線程有兩種方式:函數或者用類來包裝線程對象。

函數式:調用 _thread 模塊中的start_new_thread()函數來產生新線程。語法如下:

_thread.start_new_thread ( function, args[, kwargs] )
參數說明:

  1. function - 線程函數。
  2. args - 傳遞給線程函數的參數,他必須是個tuple類型。
  3. 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

案例

簡單的應用瞭解了我們實際練習一下簡單案例

  1. 用多線程構造新的列表,將每個元素做平方計算

注意:

  • 線程設置中的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()
  1. 計算列表元素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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章