Python3-threading模塊-多線程


什么是線程?

  線程是操作系統能夠進行運算調度的最小單位。它被包含在進程之中,是進程中的實際運作單位。一條線程指的是進程中一個單一順序的控制流,一個進程中可以並發多個線程,每條線程並行執行不同的任務

Python3中實現多線程有兩種方式

  1.直接實例化threading.Thread線程對象,實現多線程

import threading
import time


def print_age(who, age):
    """
    需要用多線程調用的函數
    :param who:
    :param age:
    :return:
    """
    print("Hello,every one!")
    time.sleep(1)
    print("%s is %s years old !" % (who, age))

if __name__ == "__main__":
    t1 = threading.Thread(target=print_age, args=("jet", 18, ))     # 創建線程1
    t2 = threading.Thread(target=print_age, args=("jack", 25, ))    # 創建線程2
    t3 = threading.Thread(target=print_age, args=("jack", 25,))     # 創建線程3
    t1.start()    # 運行線程1
    t2.start()    # 運行線程2
    t3.start()    # 運行線程3
    print("over...")
View Code

  2.通過繼承threading.Thread,並重寫run()方法,來實現多線程

import threading
import time


class MyThread(threading.Thread):
    """
    使用繼承的方式實現多線程
    """
    def __init__(self, who):
        super().__init__()    # 必須調用父類的構造方法
        self.name = who

    def run(self):
        print("%s is run..." % self.name)
        time.sleep(3)

if __name__ == "__main__":
    t1 = MyThread("Jet")    # 創建線程1
    t2 = MyThread("Jack")   # 創建線程2
    t1.start()              # 運行線程1
    t2.start()              # 運行線程2
    print("over...")
View Code

守護線程

  可以通過setDaemon()方法將線程設置為守護線程,當守護線程退出時,由它啟動的其它子線程將同時退出,不管是否執行完成

import threading
import time


def print_age(who, age):
    print("Hello,every one!")
    time.sleep(1)
    print("%s is %s years old !" % (who, age))


def daemon_func():
    for i in range(18, 25):
        t = threading.Thread(target=print_age, args=("Jet", i,))  # 創建線程
        t.start()


if __name__ == "__main__":
    dt = threading.Thread(target=daemon_func)     # 創建線程
    dt.setDaemon(True)      # 設置為守護線程
    dt.start()
    dt.join(timeout=2)
    print("over...")
View Code

線程鎖

  因為多線程是共享父進程里面的數據的,所以當多個線程同時修改一份數據的時候,就容易出錯,因此就有了鎖,鎖能確保在同一時間只有一個線程修改這份數據

  CPython的GIL(Global Interpreter Lock)是全局線程鎖,是確保只有一個線程運行的,與這個鎖沒有關系,鎖的層級不一樣,GIL更為底層

# -*- coding: utf-8 -*-
import threading
import time


def add_one():
    global num
    print("Value: %s" % num)
    time.sleep(1)
    lock.acquire()    # 加鎖
    num += 1          # 修改數據
    lock.release()    # 釋放鎖


if __name__ == "__main__":
    num = 0
    lock = threading.RLock()     # 一般都用RLock遞歸鎖
    thread_list = []
    for i in range(100):
        t = threading.Thread(target=add_one)
        t.start()
        thread_list.append(t)
    for i in thread_list:
        i.join()
    print("Num = %s" % num)
View Code

信號量

  信號量semaphore,是一個變量,控制着對公共資源或者臨界區的訪問。信號量維護着一個計數器,指定可同時訪問資源或者進入臨界區的線程數。用來控制最大線程數的

# -*- coding: utf-8 -*-
import threading
import time


def add_one():
    global num
    semaphore.acquire()    # 加鎖,最多有五個線程做以下操作
    time.sleep(1)
    num -= 1
    print("Value: %s" % num)
    semaphore.release()    # 釋放鎖


if __name__ == "__main__":
    num = 100
    thread_list = []
    semaphore = threading.BoundedSemaphore(5)

    for i in range(100):
        t = threading.Thread(target=add_one)
        t.start()
        thread_list.append(t)
    for i in thread_list:
        i.join()        # 等待線程結束
    print("Num = %s" % num)
View Code

參考資料

  http://python.usyiyi.cn/translate/python_352/library/threading.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM