Python之線程編程(Thread)

線程基本概念

    1. 什麼是線程

        【1】 線程被稱爲輕量級的進程

        【2】 線程也可以使用計算機多核資源,是多任務編程方式

        【3】 線程是系統分配內核的最小單元

        【4】 線程可以理解爲進程的分支任務

    2. 線程特徵

        【1】 一個進程中可以包含多個線程

        【2】 線程也是一個運行行爲,消耗計算機資源

        【3】 一個進程中的所有線程共享這個進程的資源

        【4】 多個線程之間的運行互不影響各自運行

        【5】 線程的創建和銷燬消耗資源遠小於進程

        【6】 各個線程也有自己的ID等特徵

threading模塊創建線程

    【1】 創建線程對象

from threading import Thread

t = Thread()

功能:創建線程對象

參數:target 綁定線程函數

           args 元組 給線程函數位置傳參

           kwargs 字典 給線程函數鍵值傳參

    【2】 啓動線程

t.start()

    【3】 回收線程

t.join([timeout])

示例1:

"""
    線程示例
"""

import threading
from time import sleep
import os

a = 1


def music():
    global a
    print("子進程a:", a)  # a = 1
    a = 10000
    for i in range(5):
        sleep(2)
        print(os.getpid(), "播放心如止水", i)  # pid = 28512


# 子線程
t = threading.Thread(target=music)
t.start()

# 主線程任務
for i in range(3):
    sleep(3)
    print(os.getpid(), "跳舞吧")  # pid = 28512
t.join()

# 主線程獲取到的a 已經被子線程更改爲10000,同時和子線程擁有相同的進程PID
print("主線程a:", a)

示例2:

from threading import Thread
from time import sleep


# 含有參數的線程函數
def fun(sec, name):
    print("線程函數傳參")
    sleep(sec)
    print("%s 線程執行完畢" % name)


jobs = []
for i in range(5):
    t = Thread(target=fun, args=(2, "t%d" % i))
    jobs.append(t)
    t.start()

for i in jobs:
    i.join()

線程對象屬性

t.name 線程名稱

t.setName() 設置線程名稱

t.getName() 獲取線程名稱

t.is_alive() 查看線程是否在生命週期(是否已啓動)

t.daemon 設置主線程和分支線程的退出關係

t.setDaemon() 設置daemon屬性值

t.isDaemon() 查看daemon屬性值

daemon爲True時主線程退出分支線程也退出。要在start前設置,通常不和join一起使用。

示例:

from threading import Thread
from time import sleep


def fun():
    sleep(3)
    print("屬性測試")


# 線程名稱,默認Thread-1,可以初始化時通過name參數自定義,或者初始化後再重新設置
t = Thread(target=fun, name="teen")
# 修改名稱
# t.setName('teen')
print("Thread name:", t.getName())

# 一般主線程只是創建子線程,具體事物由子線程去執行,
# 所以子線程執行完,主進程也就結束了,當主線程結束時,只要daemon爲True,子線程自動回收,不需要子線程調用join
t.setDaemon(True)
t.start()

# 線程生命週期,啓動後爲Tru,結束後或者未啓動時爲False
print("is alive:", t.is_alive())

自定義線程類

    1. 創建步驟

        【1】 繼承Thread

        【2】 重寫 __init__ 方法添加自己的屬性,使用super()加載父類屬性

        【3】 重寫run()方法

    2. 使用方法

        【1】 實例化對象

        【2】 調用start() 自動執行run方法

        【3】 調用join() 回收線程

示例:

"""
    自定義線程類
"""
from threading import Thread
import time


class MyThread(Thread):
    def __init__(self, attr):
        super().__init__()
        self.attr = attr

    @staticmethod
    def fun1():
        print("步驟1")

    def fun2(self):
        self.fun1()
        print("步驟2")

    def fun3(self):
        self.fun2()
        print("步驟3")

    def run(self):
        self.fun3()
        time.sleep(3)
        print("完成")


if __name__ == '__main__':
    t = MyThread("參數")
    t.start()
    t.join()

多線程併發模型

示例:

from threading import Thread
from socket import *

HOST = '0.0.0.0'
PORT = 8888
ADDR = (HOST, PORT)

# 創建套接字
s = socket()
s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
s.bind(ADDR)
s.listen(3)


def handle(c):
    print("客戶端:", c.getpeername())
    while True:
        data = c.recv(1024)
        if not data:
            break
        print(data.decode())
        c.send(b'OK')
    c.close()


# 監聽客戶端連接
while True:
    try:
        c, addr = s.accept()
    except Exception as e:
        print(e)
        continue

    # 接收到客戶端連接,創建子線程去處理
    t = Thread(target=handle, args=(c,))
    t.setDaemon(True)  # 分支線程隨主線程退出
    t.start()

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章