Python中的多工:多執行緒

SilenceHL發表於2021-04-27

多執行緒

簡介

在日常中經常使用多工操作,多執行緒通常是使用最多的一種。

併發

指任務數多餘cpu核數,通過作業系統的任務排程演算法快速切換任務,從而實現多工

並行

指任務數小於等於cpu核心數,作業系統可以分配不同的核心同時去實現多工

執行緒

定義

程式的最小執行流單元,是程式中一個單一的順序控制流程

python中實現多執行緒的模組

thread和threading,不過threading更高階,是封裝thread得到的

簡單的多執行緒

import threading
import time
def run():
    print("我要減肥!")
    time.sleep(1)
if __name__ == '__main__':
    print(time.ctime())
    for i in range(10):
        t = threading.Thread(target=run)
        t.start()
    print(time.ctime())

補充:在python3中主程式會等待子程式結束後再結束

我們可以通過enumerate方法來檢視當前執行的執行緒數量

import threading
import time
def run():
    """跑步"""
    for i in range(3):
        print("我要減肥!")
        time.sleep(1)
if __name__ == '__main__':
    t = threading.Thread(target=run)
    t.start()
    len = len(threading.enumerate())
    print('當前執行的執行緒數為:%d' % len)

多執行緒間是共享全域性變數的

栗子

import threading
import time

weight = 130


def run():
    """跑步"""
    global weight
    for i in range(3):
        print("我要減肥!")
        weight -= 1


def eat():
    """吃東西"""
    global weight
    for i in range(3):
        print("我吃了一頓好吃的")
        weight += 2


if __name__ == '__main__':
    t_run = threading.Thread(target=run)
    t_eat = threading.Thread(target=eat)
    t_run.start()
    t_eat.start()
    time.sleep(0.5)
    print(weight)

由於多個執行緒都可以修改全域性變數,會出現資源競爭,導致最後得到的資料可能不是我們想要的。

import threading
import time

weight = 130

def run():
    """跑步"""
    global weight
    for i in range(3):
        # print("我要減肥!")
        weight -= 1
    print(weight)

def eat():
    """吃東西"""
    global weight
    for i in range(3):
        # print("我吃了一頓好吃的")
        weight += 1
    print(weight)

def sedentariness():
    """久坐"""
    global weight
    for i in range(3):
        weight += 1
    print(weight)

if __name__ == '__main__':
    t_run = threading.Thread(target=run)
    t_eat = threading.Thread(target=eat)
    t_sedentariness = threading.Thread(target=sedentariness)
    # t_run.start()
    t_eat.start()
    t_sedentariness.start()

這裡我們可以看到eat方法和sendentariness方法都是加weight,我們想得到兩個133,但是最後結果是一個133,一個136.(tips:執行緒只有在呼叫了start方法才會開啟,這裡沒有呼叫run的start方法,所以沒有開啟run方法的執行緒)

這時候我們可以加上互斥鎖,在一個執行緒使用全域性變數時其他執行緒不能修改

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章