Python多執行緒程式設計(二)
我在Python多執行緒程式設計(一) 這篇文章中記錄了一下threading模組的常用方法和兩種寫run()函式的方法。這篇文章寫一下自己遇到過的幾個問題,通過例項重新理解下join()函式,以及多執行緒修改全域性變數時的坑。
首先明確下下join()函式的作用:主執行緒A中建立了一個子執行緒B,並且在主執行緒中呼叫B.join()方法。那麼主執行緒就會在呼叫B.join()這個地方等待,直到子執行緒B完成操作或者子執行緒B超時,主執行緒A才可以繼續往下面執行其他語句
1. 每個執行緒操作一個全域性變數進行累加,最後結果應該是什麼?
下面程式碼中用了10個執行緒去執行一個10000 次的for迴圈,以此累加**COUNT **這個全域性變數,我們COUNT值累加後會是10000嗎?或者是其他的值?
指令碼 1.py
[yantao@yantao thread]$ cat 1.py
#/usr/bin/python
#coding: utf-8
import threading
COUNT = 0
class AddUp(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
global COUNT
for i in xrange(10000):
COUNT += 1
print 'Current result: ',COUNT
if __name__ == '__main__':
for i in range(10):
thread = AddUp()
thread.start()
thread.join()
print 'COUNT: ',COUNT
執行結果如下:
[yantao@yantao thread]$ python 1.py
Current result: 10000
Current result: 20000
Current result: 30000
Current result: 40000
Current result: 50000
Current result: 60000
Current result: 70000
Current result: 80000
Current result: 90000
Current result: 100000
COUNT: 100000
最後的結果是100000,和“預期”結果相符合。但是,事實並不是這樣的,我們的目的是10個執行緒併發累加得到COUNT的值。1.py 指令碼雖然在主執行緒中又產生了10個執行緒,但實際上這10個執行緒是序列的,並不是並行的!
為什麼呢?來分析下產生執行緒的程式碼:
if __name__ == '__main__':
for i in range(10):
thread = AddUp()
thread.start()
thread.join()
print 'COUNT: ',COUNT
我們觀察到子執行緒thread在start()後,我們在主執行緒中立刻呼叫了thread執行緒的join()函式,以此來阻塞當前執行緒(主執行緒)。那麼我們的主執行緒就會停留在join()函式這裡,直到子執行緒返回結果後,主執行緒才會繼續執行for迴圈產生新的執行緒,但是我們繼續呼叫了新執行緒的join()方法,主執行緒會繼續等待直到新的子執行緒返回結果才會繼續執行。如此反覆10次。從這個邏輯可以看出,這裡並沒有併發,只不過是用了10個執行緒分別迴圈10000次,做了主執行緒迴圈100000次就可以做到的事情。 那麼如何做到併發了?只要對1.py稍作更改即可,如下2.py
指令碼 2.py
#/usr/bin/python
#coding: utf-8
import threading
COUNT = 0
class AddUp(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
global COUNT
for i in xrange(10000):
COUNT += 1
if __name__ == '__main__':
threads = []
for i in range(10):
thread = AddUp()
#print thread.getName()
threads.append(thread) #將所有子執行緒放在一個列表裡面
thread.start() #執行緒執行後不阻塞主執行緒,繼續執行for迴圈產生新的執行緒
for thread in threads: #在此處阻塞主執行緒,直到所有子執行緒返回
thread.join()
print COUNT
多次執行程式看下結果:
[yantao@yantao thread]$ python 2.py
53359
[yantao@yantao thread]$ python 2.py
47909
[yantao@yantao thread]$ python 2.py
52725
從結果看每次執行的並不一樣,這說明這裡確實是併發了,但是為什麼值會不一樣了?因為多個執行緒操作一個全域性變數時,會發生資源搶佔,變數不能按照預定的邏輯進行操作,比如我們這裡得到得結果就不是100000.
在使用多執行緒時,儘量避免操作全域性變數,以免引發不必要得麻煩,如果非要用,應該做好鎖機制。
相關文章
- python 多執行緒程式設計Python執行緒程式設計
- Python多執行緒程式設計Python執行緒程式設計
- python多執行緒程式設計1— python對多執行緒的支援Python執行緒程式設計
- 多執行緒程式設計基礎(二)-- 執行緒池的使用執行緒程式設計
- 多執行緒程式設計執行緒程式設計
- python多執行緒程式設計3: 使用互斥鎖同步執行緒Python執行緒程式設計
- Java多執行緒程式設計——進階篇二Java執行緒程式設計
- JavaScript多執行緒程式設計JavaScript執行緒程式設計
- Boost多執行緒程式設計執行緒程式設計
- UNIX多執行緒程式設計執行緒程式設計
- 多執行緒程式設計(轉)執行緒程式設計
- 【多執行緒高併發程式設計】二 實現多執行緒的幾種方式執行緒程式設計
- .NET多執行緒程式設計(1):多工和多執行緒 (轉)執行緒程式設計
- 使用執行緒池優化多執行緒程式設計執行緒優化程式設計
- iOS多執行緒程式設計:執行緒同步總結iOS執行緒程式設計
- .NET多執行緒程式設計(3):執行緒同步 (轉)執行緒程式設計
- [短文速讀 -5] 多執行緒程式設計引子:程式、執行緒、執行緒安全執行緒程式設計
- GCD 與多執行緒程式設計GC執行緒程式設計
- IOS多執行緒程式設計:概述iOS執行緒程式設計
- C#多執行緒程式設計C#執行緒程式設計
- linux 多執行緒程式設計Linux執行緒程式設計
- 多執行緒程式設計ExecutorService用法執行緒程式設計
- 29. 多執行緒程式設計執行緒程式設計
- Python 多執行緒多程式Python執行緒
- .NET多執行緒程式設計(4):執行緒池和非同步程式設計 (轉)執行緒程式設計非同步
- 程式設計思想之多執行緒與多程式(3):Java 中的多執行緒程式設計執行緒Java
- Python併發程式設計之建立多執行緒的幾種方法(二)Python程式設計執行緒
- 多執行緒程式設計,處理多執行緒的併發問題(執行緒池)執行緒程式設計
- Python並行程式設計(二):多執行緒鎖機制利用Lock與RLock實現執行緒同步Python並行行程程式設計執行緒
- Python——程式、執行緒、協程、多程式、多執行緒(個人向)Python執行緒
- 多執行緒程式設計基礎(一)-- 執行緒的使用執行緒程式設計
- python 程式、執行緒 (二)Python執行緒
- 多執行緒程式設計總結:一、認識多執行緒本質執行緒程式設計
- python的學習(七)----多執行緒程式設計(1)Python執行緒程式設計
- 程式設計思想之多執行緒與多程式(4):C++ 中的多執行緒程式設計執行緒C++
- 【Python】 多程式與多執行緒Python執行緒
- [02] 多執行緒邏輯程式設計執行緒程式設計
- Java多執行緒程式設計基礎Java執行緒程式設計