Python中的多進程與多線程(二)

  在上一章中,學習了Python多進程編程的一些基本方法:使用跨平臺多進程模塊multiprocessing提供的Process、Pool、Queue、Lock、Pipe等類,實現子進程建立、進程池(批量建立子進程並管理子進程數量上限)以及進程間通訊。這一章學習下Python下的多線程編程方法。python

1、threading

線程是操做系統執行任務的最小單元。Python標準庫中提供了threading模塊,對多線程編程提供了很便捷的支持。編程

下面是使用threading實現多線程的代碼:多線程

 1 #!/usr/bin/python
 2 # -*- coding: utf-8 -*
 3 __author__ = 'zni.feng'
 4 import  sys
 5 reload (sys)
 6 sys.setdefaultencoding('utf-8')
 7 
 8 import threading, time
 9 
10 def test(index):
11     print time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
12     print 'thread %s starts.' % threading.current_thread().name
13     print 'the index is %d' % index
14     time.sleep(3)
15     print time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
16     print 'thread %s ends.' % threading.current_thread().name
17 
18 if __name__ == "__main__":
19     print time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
20     print 'thread %s starts.' % threading.current_thread().name
21     #建立線程
22     my_thread = threading.Thread(target = test, args=(1,) , name= 'zni_feng_thread')
23     #等待2s
24     time.sleep(2)
25     #啓動線程
26     my_thread.start()
27     #等待線程結束
28     my_thread.join()
29     print time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
30     print 'thread %s ends.' % threading.current_thread().name

輸出結果爲:函數

2017-01-12 22:06:32
thread MainThread starts.
2017-01-12 22:06:34
thread zni_feng_thread starts.
the index is 1
2017-01-12 22:06:37
thread zni_feng_thread ends.
2017-01-12 22:06:37
thread MainThread ends.
[Finished in 5.1s]

 其中,threading模塊的current_thread()函數會返回當前線程的實例。學習

2、Lock

多進程與多線程的最大不一樣在於,多進程中,同一個變量,各自有一份拷貝存在於每一個進程中,互不影響。而多線程中,全部變量都由全部線程共享,因此,任何一個共享變量均可以被任何一個線程修改。所以線程之間共享數據最大的危險在於多個線程同時改變一個變量。爲了解決這個問題,咱們能夠藉助於threading模塊的Lock類給共享變量加鎖。ui

先看看使用多線程寫同一個共享變量,不加鎖的例子:spa

 1 #!/usr/bin/python
 2 # -*- coding: utf-8 -*
 3 __author__ = 'zni.feng'
 4 import  sys
 5 reload (sys)
 6 sys.setdefaultencoding('utf-8')
 7 import threading
 8 
 9 class Account:
10     def __init__(self):
11         self.balance = 0
12 
13     def add(self):
14         for i in range(0,100000):
15             self.balance += 1
16 
17     def delete(self):
18         for i in range(0,100000):
19             self.balance -=1 
20 
21 if __name__ == "__main__":
22     account  = Account()
23     #建立線程
24     thread_add = threading.Thread(target=account.add, name= 'Add')
25     thread_delete = threading.Thread(target=account.delete, name= 'Delete')
26 
27     #啓動線程
28     thread_add.start()
29     thread_delete.start()
30     
31     #等待線程結束
32     thread_add.join()
33     thread_delete.join()
34 
35     print 'The final balance is: ' + str(account.balance)

運行結果爲:操作系統

The final balance is: -51713
[Finished in 0.1s]

能夠發現,每次運行,它的最終結果都會不一樣,並且都不是0。就是由於不一樣線程在同時修改同一個變量時,發生了衝突,某些中間變量沒有按順序被使用致使。線程

如今咱們使用Lock對程序進行加鎖:code

 1 #!/usr/bin/python
 2 # -*- coding: utf-8 -*
 3 __author__ = 'zni.feng'
 4 import  sys
 5 reload (sys)
 6 sys.setdefaultencoding('utf-8')
 7 import threading
 8 
 9 class Account:
10     def __init__(self):
11         self.balance = 0
12 
13     def add(self, lock):
14         #得到鎖
15         lock.acquire()
16         for i in range(0,100000):
17             self.balance += 1
18         #釋放鎖
19         lock.release()
20 
21     def delete(self, lock):
22         #得到鎖
23         lock.acquire()
24         for i in range(0,100000):
25             self.balance -=1 
26         #釋放鎖
27         lock.release()
28 
29 
30 if __name__ == "__main__":
31     account  = Account()
32     lock = threading.Lock()
33     #建立線程
34     thread_add = threading.Thread(target=account.add, args=(lock, ), name= 'Add')
35     thread_delete = threading.Thread(target=account.delete, args=(lock, ), name= 'Delete')
36 
37     #啓動線程
38     thread_add.start()
39     thread_delete.start()
40     
41     #等待線程結束
42     thread_add.join()
43     thread_delete.join()
44 
45     print 'The final balance is: ' + str(account.balance)

能夠發現,不管如何執行多少次,balance結果都爲0。若是將每次balance計算的結果都打印出來,還會發現,當一個線程開始執行時,另外一個線程必定會等到前一個線程執行完(準確地說是lock.release()執行完)後纔開始執行。

The final balance is: 0
[Finished in 0.1s]
相關文章
相關標籤/搜索