天天看點

Python多任務實作方式(二)---多線程一.引入線程:二.普通程式與線程:.三.線程(threading):四.檢視線程數量:五.線程特點:

前言:前面講到了多程序,那麼本部落客今天來深剖實作多任務的第二種方式:

線程(threading)

文章目錄:

  • 一.引入線程:
  • 二.普通程式與線程:.
    • 1.普通程式舉例:
    • 2.線程執行:
  • 三.線程(threading):
    • 1.threading.Thread():
    • 2.start():
    • 3.join():
  • 四.檢視線程數量:
  • 五.線程特點:

一.引入線程:

衆所周知傳統的程序有兩個基本屬性:

  1. 可擁有資源的獨立機關;
  2. 可獨立排程和配置設定的基本機關;

引入線程的基本原因是,程序在

建立

、·切換·和·撤銷·時,系統必須為之付出·較大的記憶體開銷·,是以在系統中設定的

程序數量不宜過多

,程序的

切換頻率不宜太高

,這就·限制·了·并發程度·的提高。引入線程後,将傳統程序的兩個基本屬性分開,

線程作為排程和配置設定的基本機關

,進

程作為獨立配置設定資源的機關

。使用者可以建立線程來完成任務,以減少程式并發執行時付出的記憶體開銷。

  1. 程序給線程目标,線程去完成這個目标,
  2. 一個程式執行必然有一個線程(也就是主線程),一個程式執行必然有一個程序(主程序)。

二.普通程式與線程:.

1.普通程式舉例:

假定我們在執行程式時,會構造很多函數,但是如果每個函數都要完成自己的事情,在普通程式中,隻有當一個完成時才會執行另一個函數,這樣子會造成記憶體過度開銷,例如:

import time
def run():
    for _ in range(5):
        time.sleep(1)
        print("我會跑")
def sing():
    for _ in range(5):
        time.sleep(1)
        print("我會唱歌")
if __name__ == '__main__':
    run()
    sing()        
           

我們簡單的定義了兩個函數,各有各的事情要做,但是這種情況隻有當

run()

函數執行完才會去執行

sing()

函數,這樣程式會一直等待,會造成

記憶體

不必要的

開銷

,結果如下圖:

Python多任務實作方式(二)---多線程一.引入線程:二.普通程式與線程:.三.線程(threading):四.檢視線程數量:五.線程特點:

2.線程執行:

線程引入需要導包,也就是

threading

這個包,

thread

子產品是比較底層的子產品,

threading

是對

thread

包裝

。是以導入

threading

,我們先來看一下差別,然後我們來看看線程的聲明以及開啟;

import  threading
import time
def run():
    for _ in range(5):
        time.sleep(1)
        print("我會跑")
def sing():
    for _ in range(5):
        time.sleep(1)
        print("我會唱歌")
if __name__ == '__main__':
    run_thread=threading.Thread(target=run)
    sing_thread=threading.Thread(target=sing)
    run_thread.start()
    sing_thread.start()
           
Python多任務實作方式(二)---多線程一.引入線程:二.普通程式與線程:.三.線程(threading):四.檢視線程數量:五.線程特點:

三.線程(threading):

通過上面的舉例我們都已經看到了兩者的差別,線程會各幹各的事,節約了不少記憶體空間,但是怎麼使用呢--------------------------我們來看看:

1.threading.Thread():

和程序一樣建立一個

Thread對象

,來進行

建立這個線程

,

Thread

的參數有:

  • group:指定程序組,一般就預設為

    None

    ;
  • target:執行目标任務名;
  • name:程序名字;
  • args:以元組形式向執行任務傳參;
  • kwargs:以字典形式向執行任務傳參.
  • daemon:守護程式,預設值為

    None

    ;

舉例:

run_thread=threading.Thread(target=run)
sing_thread=threading.Thread(target=sing)
           

在前面進行定義的方法就可以在這兒通過此方法進行建立哦

2.start():

和程序中一樣都是用來開啟程序的,例如我們在面建立了兩個線程,那麼在此就可以進行開啟:

run_thread.start()
sing_thread.start()
           

3.join():

當主線程執行完再執行子線程,和程序一樣:

run_thread.start()
    run_thread.join()
    sing_thread.start()
           
Python多任務實作方式(二)---多線程一.引入線程:二.普通程式與線程:.三.線程(threading):四.檢視線程數量:五.線程特點:

四.檢視線程數量:

當線程有點多的時候,我們可以通過

enumerate()

來進行檢視線程的數量,如下:

import  threading
import time
count=0
def run():
    for _ in range(5):
        time.sleep(1)
        print("我會跑")
    print(threading.enumerate())
def sing():
    for _ in range(5):
        time.sleep(1)
        print("我會唱歌")
    print(threading.enumerate())

if __name__ == '__main__':
    # run()
    # sing()
    run_thread=threading.Thread(target=run)
    sing_thread=threading.Thread(target=sing)
    run_thread.start()
    sing_thread.start()
    print(threading.enumerate())
           
Python多任務實作方式(二)---多線程一.引入線程:二.普通程式與線程:.三.線程(threading):四.檢視線程數量:五.線程特點:

我們可以看到,圖中總共有三個線程,一個主線程,兩個子線程,并且有

Thread-x

來進行辨別

五.線程特點:

  1. 線程執行代碼的封裝,通過threading這個包中的Thread功能,往往會定義一個新的子類Class來繼承:threading.thread,一般情況下線程的主入口函數為run(),我們隻不過對其進行重寫而已:
import  threading
class threa(threading.Thread):
    def run(self):
        for _ in range(5):
            time.sleep(1)
            print("我會跑")
        print(threading.enumerate())
if __name__ == '__main__':
    # run()
    # sing()
    a=threa()
    run_thread=threading.Thread(target=a.run)
    run_thread.start()
    ret=len(threading.enumerate())
    print(ret)
           
Python多任務實作方式(二)---多線程一.引入線程:二.普通程式與線程:.三.線程(threading):四.檢視線程數量:五.線程特點:
  1. 多線程共享全局變量:

    對全局變量進行修改時,判斷是否對全局變量進行引用修改,如果修改了引用然後執行,讓全局變量指向了另一個新地方,如果修改了引用的資料,則不必擔心變量被分化:

舉例:

import  threading
import time
count=0
def sum():
    for i in range(10000):
        global count
        count+=1
    print(f"我是第一個:{count}")
def sum1():
    for i in range(10000):
        global count
        count+=1
    print(f"我是第二個:{count}")
if __name__ == '__main__':
    # run()
    # sing()
    sum_thread=threading.Thread(target=sum)
    sum1_thread = threading.Thread(target=sum1)
    sum_thread.start()
    sum1_thread.start()
    # run_thread.start()
    # run_thread.join()
    # sing_thread.start()
    print(f"總計為:{count}")    
           
Python多任務實作方式(二)---多線程一.引入線程:二.普通程式與線程:.三.線程(threading):四.檢視線程數量:五.線程特點:

由上圖可以看出,線程是

共享全局變量

的,但是修改全局變量需用

globa

l哦