多線程是編程過程中經常會使用到的手段,其目的是為了能提高任務執行的效率。在Python中,我們都知道實現多線程主要有2種方式:
使用threading.Thread()方法 繼承threading.Thread類
一個簡單的多線程的範例如下:
import threadingl = []n = 2max_n = 10000x = 0def countdown(): global x while x < max_n: x += 1 print '%s: %s\r\n' % (threading.currentThread().getName(), x)for i in range(n):t = threading.Thread(target=countdown) t.start()l.append(t)for t in l: t.join()
執行結果:
Thread-1: 1Thread-1: 2Thread-2: 3Thread-1: 4Thread-1: 5Thread-2: 6
執行這段程式會啟動n個線程同時對共用變數x進行交替加1操作,直到滿足條件的最大數。是不是很簡單。但是對於初學者來講,一不小心就會讓多線程變為單線程執行了。比如我們把代碼稍微改動一下:
import threadingn = 2max_n = 10000x = 0def countdown(): global x while x < max_n: x += 1 print '%s: %s\r\n' % (threading.currentThread().getName(), x)for i in range(n):t = threading.Thread(target=countdown) t.start() t.join()
執行結果:
Thread-1: 1Thread-1: 2Thread-1: 3...Thread-1: 10000
再次執行這段程式時,你會發現只啟動1個線程對x變數進行加1操作。原因就是join語句的位置不一樣,因為join會阻塞主線程的執行,所以我們不能在啟動一個子線程後就執行join,這樣會阻塞主線程啟動其它子線程(上面代碼中線程2是線上程1執行完任務之後才被啟動的,而此時已經沒有任務可做了),而應該在啟動完所有子線程之後才執行join。
另外一些時候你可能有這樣的需求。即希望主線程不要提前結束,直到所有的子線程都執行完畢;又希望在子線程啟動並執行同時,主線程不要被阻塞暫停,而是仍然繼續執行,直到主線程執行到最後才等待子線程的結束。那麼此時你就可以去掉join方法即可:
import threadingn = 2max_n = 10000x = 0def countdown(): global x while x < max_n: x += 1 print '%s: %s\r\n' % (threading.currentThread().getName(), x)for i in range(n): t = threading.Thread(target=countdown) t.start()
最後如果你希望主線程在執行完之後,不要等待子線程而直接退出,那麼可以使用setDaemon方法。設定這個方法,主線程在退出的時候不會檢查子線程是否已結束。
import threadingn = 2max_n = 10000x = 0def countdown(): global x while x < max_n: x += 1 print '%s: %s\r\n' % (threading.currentThread().getName(), x)for i in range(n): t = threading.Thread(target=countdown) t.setDaemon(True)##一定要在start之前調用,否則無效 t.start()
執行結果:
Thread-1: 1Thread-1: 2Thread-1: 3...Thread-1: 21