1. 程式人生 > >Python的Thread模組學習

Python的Thread模組學習

前言:

對於除了主執行緒外的子執行緒來說,只有兩種方法可以明確一個執行緒活動,傳遞一個回撥函式給建構函式(直接傳入要執行的方法),或者在子類中覆蓋run方法。換句話說在Thread的子類中,只有run()和__init__()方法可以覆蓋 。

主執行緒


當一個程序啟動之後,會預設產生一個主執行緒。main()函式啟動一個程序進而產生一個主執行緒。

子執行緒


通過Threading模組的Thread()類新生成的示例,傳入一個要執行的方法,或者覆蓋改寫子類中的run()方法來生成新執行緒。

主執行緒,子執行緒的關係


  • 當一個程序啟動之後,會預設產生一個主執行緒,因為執行緒是程式執行流的最小單元,當設定多執行緒時,主執行緒會建立多個子執行緒,在python中,預設情況下(其實就是setDaemon(False)),主執行緒執行完自己的任務以後,就退出了,此時子執行緒會繼續執行自己的任務,直到自己的任務結束,例子見下面一。
  • 當我們使用setDaemon(True)方法,設定子執行緒為守護執行緒時,主執行緒一旦執行結束,則全部執行緒全部被終止執行,可能出現的情況就是,子執行緒的任務還沒有完全執行結束,就被迫停止,例子見下面二。
  • 當我們使用join()時,join所完成的工作就是執行緒同步,即主執行緒任務結束之後,進入阻塞狀態,主執行緒一直等待全部的子執行緒結束之後,主執行緒自身才結束,程式退出。
    [t.join() for t in threads ]

socket.accept() & recv()方法


  • socket.accept( )阻塞執行緒的方法,如果沒有accept,就一直阻塞執行緒。
  • socket.recv( )阻塞執行緒的方法,如果沒有收到訊息就一直阻塞執行緒

socket的Server端和Client端交流(send &recv)


  • 服務端必須生成多個ClientTheread來應對不同的客戶端建立的連線,因為(conn,(ip,port)) = tcpServer.accept(),即一個客戶端的連線,socket.accept()就返回一個 (conn,(ip,port))data = conn.recv(1024)用來接受客戶端傳送過來的訊息data.decode("utf-8")來解碼,conn.send(text.encode("utf-8"))
    用來向客戶端編碼併發送訊息。
  • 一個客戶端只用生成一個socket物件A,然後A.connect()之後就可以A.recv(1024)來接收伺服器傳送過來的資料,通過tcpClientA.send(text.encode("utf-8"))來向服務端傳送編碼好的訊息。

執行緒生成方法


  • 通過將要執行的程式碼編寫為一個函式,然後將函式傳入執行緒的初始化(即建構函式)表示式中
  • 例項一個執行緒物件,然後呼叫start方法,start方法會啟用run方法進而執行run方法裡的任務或行為。
newthread = ClientThread(ip,port,window)
newthread.start()

Thread物件


Once a thread object is created, its activity must be started by calling the thread’s start() method. This invokes the run() method in a separate thread of control.

  • 主執行緒。
  • 通過主執行緒來創造其他的子執行緒。
  • 執行緒n。
  • 執行緒沒有terminate()函式(與程序的區別)。