Python 3多線程編程學習筆記-基礎篇

來源:互聯網
上載者:User

標籤:調用   __name__   服務   列表   process   工作   傳遞   sleep   守護   

本文是學習《Python核心編程》的學習筆記,介紹了Python中的全域解譯器鎖和常用的兩個線程模組:thread, threading,並對比他們的優缺點和給出簡單的列子。

全域解譯器鎖(GIL)

Python代碼的執行都是有Python虛擬機器進行控制的。當初設計Python的時候,考慮在主迴圈中只能有一個控制線程在執行,就像單核CPU進行多線程編程一樣。
怎麼做到這樣控制的呢?就是這裡的GIL來控制的,這個鎖用來保證同時只有一個線程在運行。

執行方式:

這幾個細節知識點:

  1. 當調用外部代碼(C/C++擴充的內建函數)時, GIL會保持鎖定,知道函數執行結束
  2. 對於面向I/O的Python常式,GIL會在I/O調用前被釋放,從而允許其他線程在I/O執行期間運行
  3. 如果是針對計算密集型的作業碼,該線程整個時間片內更傾向於始終佔有處理器和GIL。

所以,針對Python虛擬機器單線程(GIL)的設計原因,只有線程在執行I/O密集型的應用,才能更好的發揮Python的並發性

對比thread,threading

Python多個模組可以進行多線程編程,包括:thread,threading等。他們都可以用來建立和管理線程。
thread模組提供了基本的線程和鎖定支援,而threading模組提供了更進階別,功能更全面的線程管理。

推薦使用更進階別的threading模組,下面是一個簡單的對比:

特徵要素 thread threading
功能全面性 基本(偏底層) 全面,進階
守護進程 不支援 支援
線程同步原語 僅1個(Lock) 很多(Lock,Semaphore,Barrier...)
守護進程講解

守護進程一般是一個等待用戶端請求服務的伺服器。如果沒有用戶端請求,守護進程一般是閒置。一般把一個線程設定成守護進程,就表示這個線程是不重要的。所以進程退出時是不需要等待這個守護線程完成的。

但是原先的thread 模組是不區分守護或者非守護進程的,也就是說當主線程退出的時候,所有子線程都將終止,而不管他們是否仍在工作。如果你不想這種情況發生,那麼就可以採用threading模組。整個Python程式(一般為主線程)將在所有非守護進程退出是才會退出。

設定守護進程,線上程啟動之前設定:
thread.daemon = True

多線程實踐threading執行個體

方式1:建立一個thread執行個體,傳遞它一個函數

import threadingfrom time import sleep, ctimesleep_times = [4, 2]def loop(threadNo, sleep_time):    print(‘Start loop‘, threadNo, ‘at:‘, ctime())    sleep(sleep_time)    #Sleep一段時間    print(‘loop‘, threadNo, ‘done at:‘, ctime())def main():    print(‘starting at:‘, ctime())    threads = []    threadIds = range(len(sleep_times))    for i in threadIds:        thread = threading.Thread(target=loop, args=(i,sleep_times[i]))        threads.append(thread)    for t in threads:        # 依次啟動線程        t.start()    for t in threads:        # 等待所有線程完成        t.join() #將等待線程結束    print(‘all Done at :‘, ctime())if __name__ == ‘__main__‘:    main()

方式2:派生Thread的子類,並建立子類的執行個體

import threadingfrom time import sleep, ctimesleep_times = [4, 2]class MyThread(threading.Thread):    def __init__(self, func, args, name=‘‘):        threading.Thread.__init__(self)        self.func = func        self.name = name        self.args = args    def run(self):        self.func(*self.args)def loop(threadNo, sleep_time):    print(‘Start loop‘, threadNo, ‘at:‘, ctime())    sleep(sleep_time)  # Sleep一段時間    print(‘loop‘, threadNo, ‘done at:‘, ctime())def main():    print(‘starting at:‘, ctime())    threads = []  # 用於儲存所有線程執行個體的列表    threadIds = range(len(sleep_times))    for i in threadIds:        # 建立線程執行個體        thread = MyThread(loop, (i, sleep_times[i]))        threads.append(thread)    for t in threads:        # 依次啟動線程        t.start()    for t in threads:        # 等待所有線程完成        t.join()  # 將等待線程結束    print(‘all Done at :‘, ctime())if __name__ == ‘__main__‘:    main()
thread執行個體

由於本人使用的python3.6,這個thread已經變成_thread

import _threadfrom time import sleep, ctimesleep_times = [4, 2]def loop(threadNo, sleep_time, lock):    print(‘Start loop‘, threadNo, ‘at:‘, ctime())    sleep(sleep_time)    #Sleep一段時間    print(‘loop‘, threadNo, ‘done at:‘, ctime())    lock.release()       #釋放鎖def main():    print(‘starting at:‘, ctime())    locks = []    threadIds = range(len(sleep_times))    for i in threadIds:        #通過調用_thread.allocate_lock獲得鎖對象        lock = _thread.allocate_lock()        #通過acquire()方法取得鎖        lock.acquire()        locks.append(lock)    for i in threadIds:        # 依次啟動線程        _thread.start_new_thread(loop, (i, sleep_times[i], locks[i]))    for i in threadIds:        # 如果當前的鎖Lock沒有釋放的話,一直迴圈等待        while locks[i].locked():            pass    print(‘all Done at :‘, ctime())if __name__ == ‘__main__‘:    main()

Python 3多線程編程學習筆記-基礎篇

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.