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

來源:互聯網
上載者:User

標籤:建立   ini   delete   lan   test   返回   account   ftime   pytho   

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

一、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().name13     print ‘the index is %d‘ % index14     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().name17 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().name21     #建立線程22     my_thread = threading.Thread(target = test, args=(1,) , name= ‘zni_feng_thread‘)23     #等待2s24     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:32thread MainThread starts.2017-01-12 22:06:34thread zni_feng_thread starts.the index is 12017-01-12 22:06:37thread zni_feng_thread ends.2017-01-12 22:06:37thread MainThread ends.[Finished in 5.1s]

 其中,threading模組的current_thread()函數會返回當前線程的執行個體。

二、Lock

多進程與多線程的最大不同在於,多進程中,同一個變數,各自有一份拷貝存在於每個進程中,互不影響。而多線程中,所有變數都由所有線程共用,所以,任何一個共用變數都可以被任何一個線程修改。因此線程之間共用資料最大的危險在於多個線程同時改變一個變數。為瞭解決這個問題,我們可以藉助於threading模組的Lock類給共用變數加鎖。

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

 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 = 012 13     def add(self):14         for i in range(0,100000):15             self.balance += 116 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對程式進行加鎖:

 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 = 012 13     def add(self, lock):14         lock.acquire()15         for i in range(0,100000):16             self.balance += 117         lock.release()18 19     def delete(self, lock):20         lock.acquire()21         for i in range(0,100000):22             self.balance -=1 23         lock.release()24 25 26 if __name__ == "__main__":27     account  = Account()28     lock = threading.Lock()29     #建立線程30     thread_add = threading.Thread(target=account.add, args=(lock, ), name= ‘Add‘)31     thread_delete = threading.Thread(target=account.delete, args=(lock, ), name= ‘Delete‘)32 33     #啟動線程34     thread_add.start()35     thread_delete.start()36     37     #等待線程結束38     thread_add.join()39     thread_delete.join()40 41     print ‘The final balance is: ‘ + str(account.balance)

可以發現,無論如何執行多少次,balance結果都為0。如果將每次balance計算的結果都列印出來,還會發現,當一個線程開始執行時,另一個線程一定會等到前一個線程執行完(準確地說是lock.release()執行完)後才開始執行。

The final balance is: 0[Finished in 0.1s]

 

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.