最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python中線程編程之threading模塊的使用詳解

 更新時(shí)間:2015年06月23日 12:24:28   作者:Darkbull  
這篇文章主要介紹了Python中線程編程之threading模塊的使用詳解,由于GIL的存在,線程一直是Python編程中的焦點(diǎn)問題,需要的朋友可以參考下

threading.Thread

Thread 是threading模塊中最重要的類之一,可以使用它來創(chuàng)建線程。有兩種方式來創(chuàng)建線程:一種是通過繼承Thread類,重寫它的run方法;另一種是創(chuàng)建一個(gè)threading.Thread對(duì)象,在它的初始化函數(shù)(__init__)中將可調(diào)用對(duì)象作為參數(shù)傳入。下面分別舉例說明。先來看看通過繼承threading.Thread類來創(chuàng)建線程的例子:
 

#coding=gbk
import threading, time, random
count = 0
class Counter(threading.Thread):
 def __init__(self, lock, threadName):
  
'''@summary: 初始化對(duì)象。
   
  
@param lock: 瑣對(duì)象。
  
@param threadName: 線程名稱。
  
'''
  super(Counter, self).__init__(name = threadName) 
#注意:一定要顯式的調(diào)用父類的初始
化函數(shù)。
  self.lock = lock
  
 def run(self):
  
'''@summary: 重寫父類run方法,在線程啟動(dòng)后執(zhí)行該方法內(nèi)的代碼。
  
'''
  global count
  self.lock.acquire()
  for i in xrange(10000):
   count = count + 1
  self.lock.release()
lock = threading.Lock()
for i in range(5): 
 Counter(lock, "thread-" + str(i)).start()
time.sleep(2) 
#確保線程都執(zhí)行完畢
print count

在代碼中,我們創(chuàng)建了一個(gè)Counter類,它繼承了threading.Thread。初始化函數(shù)接收兩個(gè)參數(shù),一個(gè)是瑣對(duì)象,另一個(gè)是線程的名稱。在Counter中,重寫了從父類繼承的run方法,run方法將一個(gè)全局變量逐一的增加10000。在接下來的代碼中,創(chuàng)建了五個(gè)Counter對(duì)象,分別調(diào)用其start方法。最后打印結(jié)果。這里要說明一下run方法 和start方法: 它們都是從Thread繼承而來的,run()方法將在線程開啟后執(zhí)行,可以把相關(guān)的邏輯寫到run方法中(通常把run方法稱為活動(dòng)[Activity]。);start()方法用于啟動(dòng)線程。

再看看另外一種創(chuàng)建線程的方法:
 

import threading, time, random
count = 0
lock = threading.Lock()
def doAdd():
 
'''@summary: 將全局變量count 逐一的增加10000。
 
'''
 global count, lock
 lock.acquire()
 for i in xrange(10000):
  count = count + 1
 lock.release()
for i in range(5):
 threading.Thread(target = doAdd, args = (), name = 'thread-' + str(i)).start()
time.sleep(2) 
#確保線程都執(zhí)行完畢
print count

在這段代碼中,我們定義了方法doAdd,它將全局變量count 逐一的增加10000。然后創(chuàng)建了5個(gè)Thread對(duì)象,把函數(shù)對(duì)象doAdd 作為參數(shù)傳給它的初始化函數(shù),再調(diào)用Thread對(duì)象的start方法,線程啟動(dòng)后將執(zhí)行doAdd函數(shù)。這里有必要介紹一下threading.Thread類的初始化函數(shù)原型:

    def __init__(self, group=None, target=None, name=None, args=(), kwargs={})
    
    
  •       參數(shù)group是預(yù)留的,用于將來擴(kuò)展;
  •       參數(shù)target是一個(gè)可調(diào)用對(duì)象(也稱為活動(dòng)[activity]),在線程啟動(dòng)后執(zhí)行;
  •       參數(shù)name是線程的名字。默認(rèn)值為“Thread-N“,N是一個(gè)數(shù)字。
  •       參數(shù)args和kwargs分別表示調(diào)用target時(shí)的參數(shù)列表和關(guān)鍵字參數(shù)。

Thread類還定義了以下常用方法與屬性:

Thread.getName()

Thread.setName()

Thread.name

用于獲取和設(shè)置線程的名稱。
Thread.ident

獲取線程的標(biāo)識(shí)符。線程標(biāo)識(shí)符是一個(gè)非零整數(shù),只有在調(diào)用了start()方法之后該屬性才有效,否則它只返回None。
Thread.is_alive()
Thread.isAlive()

判斷線程是否是激活的(alive)。從調(diào)用start()方法啟動(dòng)線程,到run()方法執(zhí)行完畢或遇到未處理異常而中斷 這段時(shí)間內(nèi),線程是激活的。
Thread.join([timeout])

調(diào)用Thread.join將會(huì)使主調(diào)線程堵塞,直到被調(diào)用線程運(yùn)行結(jié)束或超時(shí)。參數(shù)timeout是一個(gè)數(shù)值類型,表示超時(shí)時(shí)間,如果未提供該參數(shù),那么主調(diào)線程將一直堵塞到被調(diào)線程結(jié)束。下面舉個(gè)例子說明join()的使用:
 

import threading, time
def doWaiting():
 print 'start waiting:', time.strftime('%H:%M:%S')
 time.sleep(3)
 print 'stop waiting', time.strftime('%H:%M:%S')
thread1 = threading.Thread(target = doWaiting)
thread1.start()
time.sleep(1) 
#確保線程thread1已經(jīng)啟動(dòng)
print 'start join'
thread1.join() 
#將一直堵塞,直到thread1運(yùn)行結(jié)束。
print 'end join'
threading.RLock和threading.Lock

在threading模塊中,定義兩種類型的瑣:threading.Lock和threading.RLock。它們之間有一點(diǎn)細(xì)微的區(qū)別,通過比較下面兩段代碼來說明:
 

import threading
lock = threading.Lock() 
#Lock對(duì)象
lock.acquire()
lock.acquire() 
#產(chǎn)生了死瑣。
lock.release()
lock.release()
 
import threading
rLock = threading.RLock() 
#RLock對(duì)象
rLock.acquire()
rLock.acquire() 
#在同一線程內(nèi),程序不會(huì)堵塞。
rLock.release()
rLock.release()

這兩種瑣的主要區(qū)別是:RLock允許在同一線程中被多次acquire。而Lock卻不允許這種情況。注意:如果使用RLock,那么acquire和release必須成對(duì)出現(xiàn),即調(diào)用了n次acquire,必須調(diào)用n次的release才能真正釋放所占用的瑣。
threading.Condition

可以把Condiftion理解為一把高級(jí)的瑣,它提供了比Lock, RLock更高級(jí)的功能,允許我們能夠控制復(fù)雜的線程同步問題。threadiong.Condition在內(nèi)部維護(hù)一個(gè)瑣對(duì)象(默認(rèn)是RLock),可以在創(chuàng)建Condigtion對(duì)象的時(shí)候把瑣對(duì)象作為參數(shù)傳入。Condition也提供了acquire, release方法,其含義與瑣的acquire, release方法一致,其實(shí)它只是簡單的調(diào)用內(nèi)部瑣對(duì)象的對(duì)應(yīng)的方法而已。Condition還提供了如下方法(特別要注意:這些方法只有在占用瑣(acquire)之后才能調(diào)用,否則將會(huì)報(bào)RuntimeError異常。):
Condition.wait([timeout]):

wait方法釋放內(nèi)部所占用的瑣,同時(shí)線程被掛起,直至接收到通知被喚醒或超時(shí)(如果提供了timeout參數(shù)的話)。當(dāng)線程被喚醒并重新占有瑣的時(shí)候,程序才會(huì)繼續(xù)執(zhí)行下去。
Condition.notify():

喚醒一個(gè)掛起的線程(如果存在掛起的線程)。注意:notify()方法不會(huì)釋放所占用的瑣。
Condition.notify_all()
Condition.notifyAll()

喚醒所有掛起的線程(如果存在掛起的線程)。注意:這些方法不會(huì)釋放所占用的瑣。

現(xiàn)在寫個(gè)捉迷藏的游戲來具體介紹threading.Condition的基本使用。假設(shè)這個(gè)游戲由兩個(gè)人來玩,一個(gè)藏(Hider),一個(gè)找(Seeker)。游戲的規(guī)則如下:1. 游戲開始之后,Seeker先把自己眼睛蒙上,蒙上眼睛后,就通知Hider;2. Hider接收通知后開始找地方將自己藏起來,藏好之后,再通知Seeker可以找了; 3. Seeker接收到通知之后,就開始找Hider。Hider和Seeker都是獨(dú)立的個(gè)體,在程序中用兩個(gè)獨(dú)立的線程來表示,在游戲過程中,兩者之間的行為有一定的時(shí)序關(guān)系,我們通過Condition來控制這種時(shí)序關(guān)系。

 

#---- Condition
#---- 捉迷藏的游戲
import threading, time
class Hider(threading.Thread):
 def __init__(self, cond, name):
  super(Hider, self).__init__()
  self.cond = cond
  self.name = name
  
 def run(self):
  time.sleep(1) 
#確保先運(yùn)行Seeker中的方法 
   
  self.cond.acquire() 
#b 
  print self.name + ': 我已經(jīng)把眼睛蒙上了'
  self.cond.notify()
  self.cond.wait() 
#c 
       
#f 
  print self.name + ': 我找到你了 ~_~'
  self.cond.notify()
  self.cond.release()
       
#g
  print self.name + ': 我贏了' 
#h
   
class Seeker(threading.Thread):
 def __init__(self, cond, name):
  super(Seeker, self).__init__()
  self.cond = cond
  self.name = name
 def run(self):
  self.cond.acquire()
  self.cond.wait() 
#a #釋放對(duì)瑣的占用,同時(shí)線程掛起在這里,直到被notify并重新占
有瑣。
       
#d
  print self.name + ': 我已經(jīng)藏好了,你快來找我吧'
  self.cond.notify()
  self.cond.wait() 
#e
       
#h
  self.cond.release() 
  print self.name + ': 被你找到了,哎~~~'
   
cond = threading.Condition()
seeker = Seeker(cond, 'seeker')
hider = Hider(cond, 'hider')
seeker.start()
hider.start()
threading.Event

Event實(shí)現(xiàn)與Condition類似的功能,不過比Condition簡單一點(diǎn)。它通過維護(hù)內(nèi)部的標(biāo)識(shí)符來實(shí)現(xiàn)線程間的同步問題。(threading.Event和.NET中的System.Threading.ManualResetEvent類實(shí)現(xiàn)同樣的功能。)
Event.wait([timeout])

堵塞線程,直到Event對(duì)象內(nèi)部標(biāo)識(shí)位被設(shè)為True或超時(shí)(如果提供了參數(shù)timeout)。
Event.set()

將標(biāo)識(shí)位設(shè)為Ture
Event.clear()

將標(biāo)識(shí)伴設(shè)為False。
Event.isSet()

判斷標(biāo)識(shí)位是否為Ture。

下面使用Event來實(shí)現(xiàn)捉迷藏的游戲(可能用Event來實(shí)現(xiàn)不是很形象)
 

#---- Event
#---- 捉迷藏的游戲
import threading, time
class Hider(threading.Thread):
 def __init__(self, cond, name):
  super(Hider, self).__init__()
  self.cond = cond
  self.name = name
  
 def run(self):
  time.sleep(1) 
#確保先運(yùn)行Seeker中的方法 
   
  print self.name + ': 我已經(jīng)把眼睛蒙上了'
   
  self.cond.set()
   
  time.sleep(1) 
   
  self.cond.wait()
  print self.name + ': 我找到你了 ~_~'
   
  self.cond.set()
        
  print self.name + ': 我贏了'
   
class Seeker(threading.Thread):
 def __init__(self, cond, name):
  super(Seeker, self).__init__()
  self.cond = cond
  self.name = name
 def run(self):
  self.cond.wait()
       
  print self.name + ': 我已經(jīng)藏好了,你快來找我吧'
  self.cond.set()
   
  time.sleep(1)
  self.cond.wait()
        
  print self.name + ': 被你找到了,哎~~~'
   
cond = threading.Event()
seeker = Seeker(cond, 'seeker')
hider = Hider(cond, 'hider')
seeker.start()
hider.start()
threading.Timer

threading.Timer是threading.Thread的子類,可以在指定時(shí)間間隔后執(zhí)行某個(gè)操作。下面是Python手冊(cè)上提供的一個(gè)例子:
 

def hello():
 print "hello, world"
t = Timer(3, hello)
t.start() 
# 3秒鐘之后執(zhí)行hello函數(shù)。

threading模塊中還有一些常用的方法沒有介紹:
threading.active_count()
threading.activeCount()

獲取當(dāng)前活動(dòng)的(alive)線程的個(gè)數(shù)。
threading.current_thread()
threading.currentThread()

獲取當(dāng)前的線程對(duì)象(Thread object)。
threading.enumerate()

獲取當(dāng)前所有活動(dòng)線程的列表。
threading.settrace(func)

設(shè)置一個(gè)跟蹤函數(shù),用于在run()執(zhí)行之前被調(diào)用。
threading.setprofile(func)

設(shè)置一個(gè)跟蹤函數(shù),用于在run()執(zhí)行完畢之后調(diào)用。

threading模塊的內(nèi)容很多,一篇文章很難寫全,更多關(guān)于threading模塊的信息,請(qǐng)查詢Python手冊(cè) threading模塊。

相關(guān)文章

  • Python關(guān)于print的操作(倒計(jì)時(shí)、轉(zhuǎn)圈顯示、進(jìn)度條)

    Python關(guān)于print的操作(倒計(jì)時(shí)、轉(zhuǎn)圈顯示、進(jìn)度條)

    這篇文章主要介紹了Python關(guān)于print的操作(倒計(jì)時(shí)、轉(zhuǎn)圈顯示、進(jìn)度條),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • Jupyter安裝鏈接aconda實(shí)現(xiàn)過程圖解

    Jupyter安裝鏈接aconda實(shí)現(xiàn)過程圖解

    這篇文章主要介紹了Jupyter安裝鏈接aconda實(shí)現(xiàn)過程圖解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • Python如何聲明以管理員方式運(yùn)行(附實(shí)戰(zhàn)案例)

    Python如何聲明以管理員方式運(yùn)行(附實(shí)戰(zhàn)案例)

    由于Windows的安全機(jī)制,Python寫的腳本缺少了管理員權(quán)限,運(yùn)行就會(huì)受到一些限制,這篇文章主要介紹了Python如何聲明以管理員方式運(yùn)行的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-04-04
  • Python實(shí)現(xiàn)的簡單模板引擎功能示例

    Python實(shí)現(xiàn)的簡單模板引擎功能示例

    這篇文章主要介紹了Python實(shí)現(xiàn)的簡單模板引擎功能,結(jié)合具體實(shí)例形式分析了Python模版引擎的定義與使用方法,需要的朋友可以參考下
    2017-09-09
  • Python虛擬環(huán)境venv用法詳解

    Python虛擬環(huán)境venv用法詳解

    這篇文章主要介紹了Python虛擬環(huán)境venv用法詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • Django ContentType組件詳解

    Django ContentType組件詳解

    這篇文章主要為大家介紹了Django ContentType組件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • Python深入學(xué)習(xí)之閉包

    Python深入學(xué)習(xí)之閉包

    這篇文章主要介紹了Python深入學(xué)習(xí)之閉包,閉包(closure)是函數(shù)式編程的重要的語法結(jié)構(gòu),Python也支持這一特性,本文就這一特性做了講解,需要的朋友可以參考下
    2014-08-08
  • Python3標(biāo)準(zhǔn)庫之dbm UNIX鍵-值數(shù)據(jù)庫問題

    Python3標(biāo)準(zhǔn)庫之dbm UNIX鍵-值數(shù)據(jù)庫問題

    dbm是面向DBM數(shù)據(jù)庫的一個(gè)前端,DBM數(shù)據(jù)庫使用簡單的字符串值作為鍵來訪問包含字符串的記錄。這篇文章主要介紹了Python3標(biāo)準(zhǔn)庫:dbm UNIX鍵-值數(shù)據(jù)庫的相關(guān)知識(shí),需要的朋友可以參考下
    2020-03-03
  • 39條Python語句實(shí)現(xiàn)數(shù)字華容道

    39條Python語句實(shí)現(xiàn)數(shù)字華容道

    這篇文章主要為大家詳細(xì)介紹了39條Python語句實(shí)現(xiàn)數(shù)字華容道,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • 詳解Python查找誰刪了你的微信

    詳解Python查找誰刪了你的微信

    微信好友長時(shí)間不聯(lián)系就可能被對(duì)方刪除,但是微信也不會(huì)主動(dòng)通知你。那么我們就來用python寫一個(gè)工具查驗(yàn)一下誰刪除了你的微信
    2022-02-02

最新評(píng)論

海原县| 柯坪县| 会同县| 建始县| 宁晋县| 五华县| 辽阳县| 宝清县| 嘉禾县| 威远县| 元朗区| 原平市| 桦甸市| 龙游县| 聂拉木县| 芮城县| 望都县| 柏乡县| 达拉特旗| 阿荣旗| 阿勒泰市| 伊宁市| 甘肃省| 景泰县| 昌吉市| 田东县| 舞阳县| 富锦市| 盐亭县| 临猗县| 永川市| 积石山| 南澳县| 松原市| 丰都县| 洮南市| 恩平市| 澄城县| 淮安市| 遂溪县| 依安县|