1. 程式人生 > >Python開發基礎-Day29多線程

Python開發基礎-Day29多線程

通信 getname spa 阻塞 str 等待 有時 acc 完成

概念

進程:進程就是一個程序在一個數據集上的一次動態執行過程

  程序:代碼

  數據集:程序執行過程中需要的資源  

  進程控制塊:完成狀態保存的單元

線程:線程是寄托在進程之上,為了提高系統的並發性

  線程是進程的實體

  進程是一個資源管理單元、線程是最小的執行單元

線程和進程的關系

技術分享

(1)一個線程只能屬於一個進程,而一個進程可以有多個線程,但至少有一個線程。
(2)資源分配給進程,同一進程的所有線程共享該進程的所有資源。
(3)CPU分給線程,即真正在CPU上運行的是線程。

進程/線程切換原則:切換的操作者,操作系統

  1、時間片,任務的處理時間

  2、遇到io操作,切換

    例如socket, accept發了一次系統調用,然後就等待操作系統調用,操作系統進行監聽

  3、優先級切換

技術分享

並發:在一個時間段裏,能夠執行多個程序的能力

切換:即任務狀態的保存,狀態的恢復,是並發的條件

  註:為了共用數據集,線程進行切換,線程切換的開銷遠遠小於進程切換的開銷

並行:多個cpu,在同一時刻能夠執行多個程序

同步:同步就是指一個進程在執行某個請求的時候,若該請求需要一段時間才能返回信息,那麽這個進程將會一直等待下去,直到收到返回信息才繼續執行下去

異步:異步是指進程不需要一直等下去,而是繼續執行下面的操作,不管其他進程的狀態。當有消息返回時系統會通知進程進行處理,這樣可以提高執行的效率。

舉個例子,打電話時就是同步通信,發短息時就是異步通信。

python的線程

python加鎖:同一時間只有一個線程出來被執行,在一個進程下實現真正意義上的線程並行,把多核的優勢給浪費了(後邊會講)

threading模塊

Thread類直接創建

 1 import threading
 2 import time
 3 
 4 def countNum(n): # 定義某個線程要運行的函數
 5 
 6     print("running on number:%s" %n)
 7 
 8     time.sleep(3)
 9 
10 if __name__ == __main__:
11 
12     t1 = threading.Thread(target=countNum,args=(23,)) #
生成一個線程實例 13 t2 = threading.Thread(target=countNum,args=(34,)) 14 15 t1.start() #啟動線程 16 t2.start() 17 18 print("ending!")

技術分享

Thread類繼承式創建

#繼承Thread式創建

import threading
import time

class MyThread(threading.Thread):

    def __init__(self,num):
        threading.Thread.__init__(self)
        self.num=num

    def run(self):
        print("running on number:%s" %self.num)
        time.sleep(3)

t1=MyThread(56)
t2=MyThread(78)

t1.start()
t2.start()
print("ending")

join()和setDaemon()

# join():在子線程完成運行之前,這個子線程的父線程將一直被阻塞。

# setDaemon(True):
        ‘‘‘
         將線程聲明為守護線程,必須在start() 方法調用之前設置,如果不設置為守護線程程序會被無限掛起。

         當我們在程序運行中,執行一個主線程,如果主線程又創建一個子線程,主線程和子線程 就分兵兩路,分別運行,那麽當主線程完成

         想退出時,會檢驗子線程是否完成。如果子線程未完成,則主線程會等待子線程完成後再退出。但是有時候我們需要的是只要主線程

         完成了,不管子線程是否完成,都要和主線程一起退出,這時就可以 用setDaemon方法啦‘‘‘


import threading
from time import ctime,sleep
import time

def Music(name):

        print ("Begin listening to {name}. {time}".format(name=name,time=ctime()))
        sleep(3)
        print("end listening {time}".format(time=ctime()))

def Blog(title):

        print ("Begin recording the {title}. {time}".format(title=title,time=ctime()))
        sleep(5)
        print(end recording {time}.format(time=ctime()))


threads = []


t1 = threading.Thread(target=Music,args=(FILL ME,))
t2 = threading.Thread(target=Blog,args=(‘‘,))

threads.append(t1)
threads.append(t2)

if __name__ == __main__:

    #t2.setDaemon(True)

    for t in threads:

        #t.setDaemon(True) #註意:一定在start之前設置
        t.start()

        #t.join()

    #t1.join()
    #t2.join()    #  考慮這三種join位置下的結果?

    print ("all over %s" %ctime())
daemon
A boolean value indicating whether this thread is a daemon thread (True) or not (False). This must be set before start() is called, otherwise RuntimeError is raised. Its initial value is inherited from the creating thread; the main thread is not a daemon thread and therefore all threads created in the main thread default to daemon = False.

The entire Python program exits when no alive non-daemon threads are left.

當daemon被設置為True時,如果主線程退出,那麽子線程也將跟著退出,

反之,子線程將繼續運行,直到正常退出。

其它方法

Thread實例對象的方法
  # isAlive(): 返回線程是否活動的。
  # getName(): 返回線程名。
  # setName(): 設置線程名。

threading模塊提供的一些方法:
  # threading.currentThread(): 返回當前的線程變量。
  # threading.enumerate(): 返回一個包含正在運行的線程的list。正在運行指線程啟動後、結束前,不包括啟動前和終止後的線程。
  # threading.activeCount(): 返回正在運行的線程數量,與len(threading.enumerate())有相同的結果。

IO密集型任務:程序中存在大量IO操作

計算密集型任務:程序中存在大量計算操作

對於python而言,處理io密集型任務有優勢,對於計算密集型任務沒優勢

Python開發基礎-Day29多線程