欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解python中的線程

 更新時間:2018年02月10日 08:34:33   作者:renpingsheng  
Python中創(chuàng)建線程有兩種方式:函數(shù)或者用類來創(chuàng)建線程對象。這篇文章主要介紹了python中的線程,需要的朋友可以參考下

Python中創(chuàng)建線程有兩種方式:函數(shù)或者用類來創(chuàng)建線程對象。

函數(shù)式:調(diào)用 _thread 模塊中的start_new_thread()函數(shù)來產(chǎn)生新線程。

類:創(chuàng)建threading.Thread的子類來包裝一個線程對象。

1.線程的創(chuàng)建

1.1 通過thread類直接創(chuàng)建   

import threading
  import time
  def foo(n):
    time.sleep(n)
    print("foo func:",n)
  def bar(n):
    time.sleep(n)
    print("bar func:",n)
  s1=time.time()
  #創(chuàng)建一個線程實例t1,foo為這個線程要運(yùn)行的函數(shù)
  t1=threading.Thread(target=foo,args=(3,))
  t1.start()  #啟動線程t1
  #創(chuàng)建一個線程實例t2,bar為這個線程要運(yùn)行的函數(shù)
  t2=threading.Thread(target=bar,args=(5,))
  t2.start()  #啟動線程t2
  print("ending")
  s2=time.time()
  print("cost time:",s2-s1)

在這段程序里,一個函數(shù)會先休眠幾秒鐘,然后再打印一句話,第二個函數(shù)也是先休眠幾秒鐘,然后打印一句話。

接著程序會實例化兩個線程,并調(diào)用兩個函數(shù)來執(zhí)行,最后會打印程序問總共執(zhí)行了多少時間

程序運(yùn)行結(jié)果如下:

ending
cost time: 0.002000093460083008
foo func: 3
bar func: 5

程序會先運(yùn)行父線程,打印"ending",然后打印程序執(zhí)行父線程的時間,最后才會運(yùn)行子線程

1.2 通過thread類來繼承式創(chuàng)建

 import threading
  import time
  # 定義MyThread類,其繼承自threading.Thread這個父類
  class MyThread(threading.Thread): 
    def __init__(self):
      threading.Thread.__init__(self)
    def run(self):
      print("ok")
      time.sleep(2)
      print("end t1")
  # 對類進(jìn)行實例化
  t1=MyThread()  
  # 啟動線程
  t1.start()
  print("ending")

2. Thread類的一些常用方法

2.1 join():在子線程完成之前,主線程將一直被阻塞****

線程的join方法必須在子線程的start方法之后定義
在第一個例子中加入兩行代碼,如下:   

import threading
  import time
  def foo(n):
    time.sleep(n)
    print("foo func:",n)
  def bar(n):
    time.sleep(n)
    print("bar func:",n)
  s1=time.time()
  t1=threading.Thread(target=foo,args=(3,))
  t1.start()
  t2=threading.Thread(target=bar,args=(5,))
  t2.start()
  t1.join()    # 阻塞t1線程
  t2.join()    # 阻塞t2線程
  print("ending")
  s2=time.time()
  print("cost time:",s2-s1)

再次執(zhí)行程序,運(yùn)行結(jié)果如下:

foo func: 3
bar func: 5
ending
cost time: 5.002285957336426

程序運(yùn)行到子線程t1中的foo方法時會睡眠3秒鐘,與此同時,子線程t2也在睡眠

等到子線程t1睡眠完成后,開始打印foo函數(shù)中的print語句,然后子線程t1執(zhí)行完成

2秒鐘之后,子線程t2睡眠完成,開始打印bar函數(shù)中的print語句,然后子線程t2也執(zhí)行完成。

而在這之前,主線程一直處于阻塞狀態(tài)。等到子線程執(zhí)行完成之后主線程才會執(zhí)行

2.2 setDeamon(True)

setDaemon方法作用是將進(jìn)程聲明為守護(hù)線程,必須在`start()`方法調(diào)用之前,
如果不設(shè)置為守護(hù)線程,程序會被無限掛起

在程序執(zhí)行過程中,執(zhí)行一個主線程,主線程又創(chuàng)建一個子線程時,主線程和子線程會分別運(yùn)行。

當(dāng)主線程運(yùn)行完成時,會檢驗子線程是否執(zhí)行完成,如果子線程執(zhí)行完成,則主線程會等待子線程完成后再退出。

但是有的時候只要主線程執(zhí)行完成之后,不管子線程是否執(zhí)行完成,都和主線程一起退出,這個就需要調(diào)用setDeamon方法了。

拿第一個例子來說吧,現(xiàn)在我想讓子線程t1和t2隨同主線程關(guān)閉,代碼如下:

 import threading
  import time
  def foo(n):
    print("foo start")
    time.sleep(n)
    print("foo end...")
  def bar(n):
    print("bar start")
    time.sleep(n)
    print("bar end...")
  s1 = time.time()
  t1 = threading.Thread(target=foo, args=(3,))
  t1.setDaemon(True)
  t1.start()
  t2 = threading.Thread(target=bar, args=(5,))
  t2.setDaemon(True)
  t2.start()
  print("ending")
  s2 = time.time()
  print("cost time:", s2 - s1)

程序運(yùn)行結(jié)果如下 :

foo start
bar start
ending
cost time: 0.003000020980834961

可以看到,把t1和t2都聲明為守護(hù)線程后,程序自上而下執(zhí)行,先執(zhí)行子線程t1中的foo方法,打印foo函數(shù)中的第一條打印語句,然后子線程t1進(jìn)入到睡眠狀態(tài)。

然后子線程t2執(zhí)行,打印bar函數(shù)中的第一條print語句,然后子線程t2進(jìn)入睡眠狀態(tài),程序切換到主線程運(yùn)行

主線程打印完"ending"語句,發(fā)現(xiàn)子線程t1和t2已經(jīng)被設(shè)置為守護(hù)線程,所以主線程不需要再等待兩個子線程執(zhí)行完成,而是立即結(jié)束,打印整個程序的執(zhí)行時間。

整個程序就跟隨主線程一起關(guān)閉了。

2.3 子線程的一些其他方法

isAlive()      #判斷一個線程是否是活動線程
getName()      #返回線程的名字
setName()      #設(shè)置線程的名字
  import threading
  import time
  def foo(n):
    time.sleep(n)
    print("foo func:", n)
  def bar(n):
    time.sleep(n)
    print("bar func:", n)
  s1 = time.time()
  t1 = threading.Thread(target=foo, args=(3,))
  t1.setDaemon(True)
  print("線程還未啟動時,判斷t1是否是活動的線程:", t1.isAlive()) # 線程還未啟動,所以是False
  t1.start() # 啟動線程
  print("線程已啟動時,判斷t1是否是活動的線程:", t1.isAlive()) # 線程已啟動,所以是True
  print("修改前的線程名為:",t1.getName()) # 獲取線程名
  t1.setName("t1")    #設(shè)置線程名
  print("修改后的線程名為:",t1.getName()) # 獲取線程名
  t1.join()
  print("線程執(zhí)行完成時,判斷t1是不否是活動的線程:", t1.isAlive()) # 線程已執(zhí)行完成,所以是False
  # print(threading.activeCount())
  print("ending")
  s2 = time.time()
  print("cost time:", s2 - s1)

程序執(zhí)行結(jié)果:

線程還未啟動時,判斷t1是否是活動的線程: False
線程已啟動時,判斷t1是否是活動的線程: True
修改前的線程名為: Thread-1
修改后的線程名為: t1
foo func: 3
線程執(zhí)行完成時,判斷t1是不否是活動的線程: False
ending
cost time: 3.001171588897705

3.threading模塊提供的一些方法

threading.currentThread()  #返回當(dāng)前的線程變量
threading.enumerate()    #返回一個包含正在運(yùn)行的線程的列表,不包括啟動前和終止后的線程
threading.activeCount()   #返回正在運(yùn)行的線程數(shù)量,等同于len(threading.enumerate())
  import threading
  import time
  def foo(n):
    time.sleep(n)
    print("foo func:", n)
  def bar(n):
    time.sleep(n)
    print("bar func:", n)
  s1 = time.time()
  t1 = threading.Thread(target=foo, args=(3,))
  t1.setDaemon(True)
  t1.start()
  t2 = threading.Thread(target=bar, args=(5,))
  t2.setDaemon(True)
  t2.start()
  print("程序中正在運(yùn)行的線程數(shù)量:",threading.activeCount())
  print("程序中當(dāng)前的線程變量:",threading.currentThread())
  print("當(dāng)前正在運(yùn)行的線程的列表:",threading.enumerate())
  print("ending")
  s2 = time.time()
  print("cost time:", s2 - s1)

程序執(zhí)行結(jié)果:

程序中正在運(yùn)行的線程數(shù)量: 3
程序中當(dāng)前的線程變量: <_MainThread(MainThread, started 7064)>
當(dāng)前正在運(yùn)行的線程的列表: [<_MainThread(MainThread, started 7064)>, <Thread(Thread-1, started daemon 6384)>, <Thread(Thread-2, started daemon 2640)>]
ending
cost time: 0.002000093460083008

總結(jié)

以上所述是小編給大家介紹的詳解python中的線程,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

最新評論