中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

python多線程開發

發布時間:2020-03-06 13:54:51 來源:網絡 閱讀:933 作者:赤色風暴 欄目:編程語言

Python的線程開發使用標準庫threading

Thread類

def  __init__(self,group=None,target=None,name=None,args(),kwargs=None,*,daemon=None)
        參數名                     含義
        target線程調用的對象,就是目標函數
        name為線程起的名字
        args為目標函數傳遞實參,元組
       kwargs為目標函數傳遞關鍵字參數,字典


線程啟動

import threading 

def worker():
    print("I'm working! wait a moment")
    
t=threading.Thread(target=worker,name='worker')   # 線程對象
t.start().                                        # 啟動

       通過threading.Thread創建一個線程對象,target是目標函數,name可以指定自己喜歡的名字,線程的啟動需要借助start方法。線程執行函數,是因為線程中就是執行代碼的,最簡單的封裝就是函數,所以本質還是函數調用。

線程退出

Python沒有提供線程的退出方法,線程在下面的情況下時會退出

    1. 線程函數內語句執行完畢

    2. 線程函數中拋出未處理的異常

import  threading 
import  time 

def worker( ):
  count=0
  while True:
      if(count>5):
        raise RuntimeError(count)
      time.sleep(1)
    print("I'm  working!")
    count+=1
        
t=threading.Thread(target=worker,name="worker")
t.start( )
print("===End===")

結果如圖所示:

python多線程開發

Python的線程沒有優先級,沒有線程組的概念。


線程的傳參

import   threading 
import   time 

def add(x,y):
    print("{} + {} = {}".format(x,y,x+y))
    
t1=threading.Thread(target=add,name="add",args(4,5))
t1.start()
time.sleep(2)

t2=threading.Thread(target=add,name="add",kwargs={"x":4;"y":5})
t2.start()
time.sleep(2)

t3=threading.Thread(target=add,name="add",args=(4,),kwargs={"y":5})
t3.start()

線程傳參和函數傳參沒什么區別,本質上就是函數傳參。


threading的屬性和方法


              名稱                         含義
    current_thread( )返回當前線程對象
    main_thread( )返回主線程對象
    active_count( )當前處于alive狀態的線程個數
    enumerate( )返回所有活著的線程的列表,不包括已經終止的線程和未開始的線程
    get_ident( )返回當前線程的ID,非0整數


import   threading
import   time 

def showthreadinfo():
  print("currentthread = {}".format(threading.current_thread()))
  print("main thread = {}".format(threading.main_thread()))
  print("active count = {}".format(threading.active_count()))
    
def worker():
  count=0
  showthreadinfo()
  while True:
      if(count>5):
          break
      time.sleep(1)
    count+=1
    print("I'm working")
        
t=threading.Thread(target=worker,name='worker')
t.start()
print('===End===')

結果如圖所示:

python多線程開發

Thread實例的屬性和方法


名稱含義
name只是一個名字,可以重新命名。getName(),setName()獲取,設置這個名詞
ident線程ID,它是非0整數,線程啟動后才會有ID,線程退出,仍可以訪問,可重復使用
is_alive()返回線程是否存活


多線程

一個進程中如果有多個線程,就是多線程,實現一種并發

import   threading
import   time 

def worker():
  count=0
  while True:
      if(count>5):
        break
    time.sleep(0.5)
    count+=1
    print("worker running")
    print(threading.current_thread().name,threading.current_thread().ident)
 
t1=threading.Thread(name="worker1",target=worker)
t2=threading.Thread(name="worker2",target=worker)
 
t1.start()
t2.start()

結果如圖所示:

python多線程開發

可以看到worker1和worker2交替執行


daemon線程和non-daemon線程

進程靠線程執行代碼,至少有一個主線程,其它的線程都是工作線程。

父線程:如果線程A中啟動了一個線程B,A就是B的父線程。

子線程:B就是A的子線程。


       Python中,構造線程的時候,可以設置daemon屬性,這個屬性必須在start方法之前設置好。線程daemon屬性,如果設定就是用戶的設置,否則就取當前線程的daemon值,主線程是non-daemon線程,即daemon=False

import time 
import threading 

def foo():
    time.sleep(3)
  for i in range(10):
      print(i)
        
t=threading.Thread(target=foo,daemon=False)
t.start()
print("Main Thread Exiting")

運行結果如圖所示:

python多線程開發

        主進程已經執行完畢,但是線程t依然在運行,主進程一直等待著線程t。當將Thread中daemon=False改為True時發現,主進程執行后立即會結束,根本不會等待t線程。


名稱含義
daemon屬性表示線程是否是daemon線程,這個值必須在start之前設置,否則引發RuntimeError異常
isDaemon是否是Daemon線程
setDaemon設置為daemon線程,必須在start方法之前設置

總結:

       線程具有一個daemon屬性,可以設置主進程結束后是否等待其他的子線程,如果不設置,取默認值None。從主線程創建的所有線程的不設置daemon屬性,則默認daemon=False。


join方法

import   time 
import   threading

def foo(n):
    for i in range(10):
        print(i)
        time.sleep(1)
       
t1=threading.Thread(target=foo,args=(10,),daemon=True)
t1.start()
t1.join()

執行結果如圖所示:

python多線程開發

      根據上面講述的daemon線程,主進程設置的dameon=True,按理說主線程執行是根本不會去等待其它的線程,也就是不會打印這些數字,但是這里卻等待了子線程的運行打印出來了,這個就是join方法的作用。

       join(timeout=None),是線程標準方法之一,一個線程中調用另一個線程的join方法,調用者將被阻塞,直到被調用的線程停止。一個線程可以被join多次,timeout是設置等待調用者多久,如果沒有設置,就一直等待,直到被調用者線程結束。


threading.local類

      Python提供了threading.local類,將這個類實例化得到一個全局對象,但是不同的線程使用這個對象存儲的數據其他線程是不可見的。

import  threading
import  time 

#全局對象
global_data=threading.local()

def worker():
    global_data=0
    for i in range(100):
        time.sleep(0.001)
        global_data+=1
    print(threading.current_thread(),global_data)
    
for i  in range(10):
    threading.Thread(target=worker).start()

運行結果如圖所示:

python多線程開發

     可以看到雖然是全局變量,但是這個變量在各個線程之間是獨立的,每個的計算結果不會對其他線程造成干擾。


     怎么證明這個是在各個線程之間獨立的呢?

import   threading 

TestData="abc"
TestLocal=threading.local()
TestLocal.x=123

print(TestData,type(TestLocal),TestLocal.x)

def worker():
    print(TestData)
    print(TestLocal)
    print(TestLocal.x)
    
worker()
print("=====")
threading.Thread(target=worker).start()

可以看下運行結果

python多線程開發

       在子線程里面打印TestLocal.x時候出錯,顯示AttributeError: "_thread._local_" object has no attribute 'x',這是因為TestLocal.x我們是在主線程里面定義的,啟動一個子線程我們并沒有這個屬性,所以報錯,從而說明threading.local定義的變量,在各個線程之間是獨立的,不能跨線程。

       threading.local類構建了一個大字典,其元素是每一線程實例的地址為key和線程對象引用線程單獨的字典的映射:

                              {id(Thread) ->  (ref(Thread), thread-local dict)}

    

 定時器Timer

       threading.Timer繼承自Thread,用來定義多久執行一個函數。

class  threading.Timer(interval,function,args=None,kwargs=None)

       start方法執行之后,Timer對象會等待interval時間,然后開始執行function函數,如果在等待階段,使用了cancal方法,就會跳過執行而結束

import   threading 
import   time 

def worker():
    print("in worker")
    time.sleep(2)
    
t=threading.Timer(5,worker)
t.start()
print(threading.enumerate())
t.cancel()
time.sleep(1)
print(threading.enumerate())

python多線程開發

可以看到,延遲5s執行worker線程,然后主線程繼續執行,打印存活的線程,就是主線程和worker線程,然后執行cancel,子線程就會被取消執行,sleep 1s后打印存活的線程就只有主線程。


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

文化| 海南省| 凉山| 陕西省| 南城县| 伊宁市| 新余市| 贡觉县| 沙湾县| 甘德县| 西乌| 萨嘎县| 嘉鱼县| 霍邱县| 凉城县| 沙湾县| 将乐县| 古浪县| 石门县| 鸡泽县| 绥江县| 双鸭山市| 年辖:市辖区| 加查县| 寻甸| 武义县| 饶平县| 屏东县| 姜堰市| 北海市| 白朗县| 乌鲁木齐市| 永顺县| 吉首市| 柳江县| 白玉县| 乐业县| 惠东县| 黄浦区| 普兰店市| 屯门区|