1. 程式人生 > >Python多執行緒小例子

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

Python多執行緒小例子