Python多執行緒小例子
Python多執行緒小例子
1、在主執行緒中建立子執行緒
下面的程式碼一共建立了三個執行緒:主執行緒、coding 執行緒和music 執行緒,最後使用thread_list 裝載執行緒
from time import ctime
import threading
def coding(language):
for i in range(5):
print('I\'m coding ',language, ' program at ', ctime() )
def music():
for i in range(5):
print('I\'m listening music at ', ctime())
if __name__ == '__main__':
print('thread %s is running...' % threading.current_thread().name)
thread_list = []
t1 = threading.Thread(target=coding, args=('Python',))
t2 = threading.Thread(target=music)
thread_list.append(t1)
thread_list.append(t2)
for t in thread_list:
t.setDaemon(True) # 設定為守護執行緒
t.start()
for t in thread_list:
t.join() # 在這個子執行緒完成執行之前,主執行緒將一直被阻塞
print('thread %s ended.' % threading.current_thread().name)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
執行效果如下:
t.join()的作用是:在子執行緒完成執行前,主執行緒將處於阻塞的狀態,否則主執行緒會一直執行,並且主執行緒執行結束後,子執行緒也一同結束。
如果我們把join去掉,則執行結果可能為:
2、lock 鎖
在多執行緒中,變數由各個執行緒共享,對共享變數,需要加鎖。
舉一個最常見的例子:我們經常在銀行存錢、取款,其中一個執行緒負責存錢,另一個執行緒負責取款。如果不加控制,很容易就把錢數算錯了。我們看看銀行是怎麼算錯錢數的:
import threading
money = 0 # 變數 money 被 t1和 t2 兩個執行緒共享
# 存錢
def put_money(sum):
global money
money += sum
# 取錢
def get_money(sum):
global money
money -= sum
def run_thread(sum):
for i in range(1000000): #執行的次數要足夠多
# 先存sum,後取sum,錢數應當為0
put_money(sum)
get_money(sum)
t1 = threading.Thread(target=run_thread, args=(100,))
t2 = threading.Thread(target=run_thread, args=(1000,))
t1.start()
t2.start()
t1.join()
t2.join()
print(money)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
在上面的例子中,我們先存sum元錢,再取sum元錢,總錢數應當一直為0。這在單執行緒中沒有問題。
然而在多執行緒中,作業系統交叉執行賦值語句,導致全域性變數被一個執行緒修改了,另一個執行緒卻不知情的情況。
因為在作業系統中,money += sum,是被拆成兩條語句執行的:
x = money + sum
money = x
這兩條語句的執行順序 很可能是亂序的,我們看看下面的表格就理解了,最後你會驚奇地發現 少了5元錢!:-(
實際結果也驗證了這一問題:
哈哈哈,我們居然多出了2900元。很顯然,銀行家們肯定不能允許這種情況發生,所以,他們也在學習如何使用lock :-)
可以通過lock解決這個問題:
def run_thread(sum):
for i in range(1000000):
lock.acquire() # 改動1...........加鎖
try:
put_money(sum)
get_money(sum)
finally:
lock.release() # 改動2......別忘了釋放鎖:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
“當多個執行緒同時執行lock.acquire()時,只有一個執行緒能成功地獲取鎖,然後繼續執行程式碼,其他執行緒就繼續等待直到獲得鎖為止。”————引用自多執行緒-廖雪峰的官方網站
其實和上廁所一個道理,一個人蹲坑,另一個人只能等著 :-)
這下好了,銀行家們在 run_thread 方法中添加了lock,這次程式執行的結果如下,我們看到錢數始終為0:
除了多執行緒外,Python 多程序也經常使用,參見:
http://blog.csdn.net/u010429424/article/details/76147368
參考:
http://www.cnblogs.com/fnng/p/3670789.html
https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00143192823818768cd506abbc94eb5916192364506fa5d000