Python線程

多任務

  • 概念:操作系統可以同時運行多個任務

  • 併發:指的是任務數多餘cpu核數,通過操作系統的各種任務調度算法,實現用多個任務在同一時間段執行(實際上總有一些任務不在執行,因爲切換任務的速度相當快,看上去一起執行而已)

  • 並行:指的是多核cpu情況下,多個任務的一些任務往往在同一時間點執行

線程

  • 概念:就是一個進程內部的一條代碼執行流程

  • 默認存在的就是主線程,新創建出來的叫做子線程

創建線程

使用threading模塊 或繼承threading.Thread

  • target 指定線程執行的函數名

  • args 指定函數的參數

  • enumerate() 查看當前進程中的線程列表

  • join() 主線程等待子線程執行完成後,才能繼續往下運行

多線程共享全局變量,如果多個線程同時對同一個全局變量操作,會出現資源競爭問題,從而數據結果會不正確

同步:就是協同步調,按預定的先後次序進行運行

互斥鎖

  • 概念:某個線程要更改共享資源時,先將其鎖定,此時資源的狀態爲”鎖定”,其他線程不能更改;直到該線程釋放資源,將資源的狀態變成”非鎖定”,其他的線程才能再次鎖定該資源。互斥鎖保證了每次只有一個線程進行寫入操作,從而保證了多線程情況下數據的正確性

創建使用互斥鎖

# 創建鎖
mutex = threading.Lock()
#  鎖定
mutex.acqire()
# 釋放
mutex.release()

優缺點

優點:確保某段關鍵代碼只能有一個線程從頭到尾完整的執行

缺點:
* 阻止了多線程併發執行,包含鎖的某段代碼實際上只能以單線程模式執行,效率大大的下降了

  • 由於可以存在多個鎖,不同的線程持有不同的鎖,並試圖獲取對方持有的鎖時,可能會造成死鎖

死鎖

  • 概念:在線程間共享多個資源的時候,如果兩個線程分別佔有一部分資源並且同時等待對方的資源,就會造成死鎖

主要原因

  • 沒有正確釋放

  • 資源分配不當

避免死鎖

  • 程序設計時要儘量避免

  • 附加超時 時間等

線程實現簡單的多任務聊天程序

import socket
import threading


def send_msg(udp_socket):
    """獲取輸入數據,並將其發送給對方"""
    msg_num = input("請輸入要發送的數據:")
    dest_ip = input("請輸入對方ip地址:")
    dest_port = int(input("請輸入對方端口號:"))
    udp_socket.sendto(msg_num.encode(), (dest_ip, dest_port))


def recv_msg(udp_socket):
    """循環接收並顯示數據"""
    while True:
        recv_msug, recv_ip = udp_socket.recvfrom(1024)
        print("接收到%s的數據:%s" % (str(recv_ip), recv_msug.decode("gbk")))


def main():
    # 創建套接字
    udp_socekt = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # 綁定端口
    udp_socekt.bind(("", 6666))

    # 創建一個子線程(收數據)
    recv_thd = threading.Thread(target=recv_msg, args=(udp_socekt,))
    recv_thd.start()

    while True:
        # 選擇功能
        print("=" * 30)
        print("1.發送消息")
        print("2.接收消息")
        print("3.退出")
        print("=" * 30)
        op_num = input("請輸入你要進行的操作:")
        if op_num == "1":
            send_msg(udp_socekt)
        # elif op_num == "2":
            # recv_msg(udp_socekt)
        elif op_num == "3":
            print("歡迎下次使用")
            break
        else:
            print("輸入有誤!請重新輸入")


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