欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

python多線(xiàn)程用法實(shí)例詳解

系統(tǒng) 1612 0

本文實(shí)例分析了python多線(xiàn)程用法。分享給大家供大家參考。具體如下:

今天在學(xué)習(xí)嘗試學(xué)習(xí)python多線(xiàn)程的時(shí)候,突然發(fā)現(xiàn)自己一直對(duì)super的用法不是很清楚,所以先總結(jié)一些遇到的問(wèn)題。當(dāng)我嘗試編寫(xiě)下面的代碼的時(shí)候:

復(fù)制代碼 代碼如下:
class A():
??? def __init__( self ):
??????? print "A"
class B( A ):
??? def __init__( self ):
??????? super( B, self ).__init__(? )
# A.__init__( self )
??????? print "B"
b = B()

出現(xiàn):

super( B, self ).__init__()

TypeError: must be type, not classobj

最后發(fā)現(xiàn)原來(lái)是python中的新式類(lèi)的問(wèn)題,也就是A必須是新式類(lèi)。解決方法如下兩種:

(1)

復(fù)制代碼 代碼如下:
class A( object ):
??? def __init__( self ):
??????? print "A"
class B( A ):
??? def __init__( self ):
??????? super( B, self ).__init__(? )
# A.__init__( self )?????? ##這條語(yǔ)句是舊式的,存在潛在的問(wèn)題,應(yīng)該避免使用
??????? print "B"
b = B()

(2)

復(fù)制代碼 代碼如下:
__metaclass__=type
class A():
??? def __init__( self ):
??????? print "A"
class B( A ):
??? def __init__( self ):
??????? super( B, self ).__init__(? )
# A.__init__( self )??? ##這條語(yǔ)句是舊式的,存在潛在的問(wèn)題,應(yīng)該避免使用
??????? print "B"
b = B()

注意 :如果在super( B, self ).__init__(? )

語(yǔ)句中添加self,也就是super( B, self ).__init__( self ),會(huì)出現(xiàn)如下的錯(cuò)誤:

??? super( B, self ).__init__( self )

TypeError: __init__() takes exactly 1 argument (2 given)

以上只是一點(diǎn)點(diǎn)本人的心得筆記,呵呵。

復(fù)制代碼 代碼如下:
import threading, time
class myThread( threading.Thread ):
??? def __init__( self, threadname = "" ):
??????? #threading.Thread.__init__( self, name = threadname )
??????? super( myThread, self ).__init__( name = threadname )
??? def run( self ):
??????? print "starting====", self.name, time.ctime()
??????? time.sleep( 5 )
??????? print "end====", self.name, time.ctime(),
?
m = myThread( "m" )
n = myThread( "n" )
?
m.start()
n.start()

輸出的結(jié)果:

starting==== m Mon Aug 08 21:55:41 2011

starting==== n Mon Aug 08 21:55:41 2011

如果一個(gè)進(jìn)程的主線(xiàn)程運(yùn)行完畢而子線(xiàn)程還在執(zhí)行的話(huà),那么進(jìn)程就不會(huì)退出,直到所有子線(xiàn)程結(jié)束為止。比如下面的例子:

復(fù)制代碼 代碼如下:
import threading, time
class myThread( threading.Thread ):
??? def __init__( self, threadname = "" ):
??????? #threading.Thread.__init__( self, name = threadname )
??????? super( myThread, self ).__init__( name = threadname )
??? def run( self ):
??????? print "starting====", self.name, time.ctime()
??????? time.sleep( 5 )
??????? print "end====", self.name, time.ctime(),
?
m = myThread( "m" )
m.start()
print "main end"
print

輸出的結(jié)果為:

starting==== m Mon Aug 08 22:01:06 2011

main end

end==== m Mon Aug 08 22:01:11 2011

也就是主進(jìn)程結(jié)束之后,子進(jìn)程還沒(méi)有結(jié)束

如果我們想在主進(jìn)程結(jié)束的時(shí)候,子進(jìn)程也結(jié)束的話(huà),我們就應(yīng)該使用setDaemon()函數(shù)。

實(shí)例如下:

復(fù)制代碼 代碼如下:
import threading, time
class myThread( threading.Thread ):
??? def __init__( self, threadname = "" ):
??????? #threading.Thread.__init__( self, name = threadname )
??????? super( myThread, self ).__init__( name = threadname )
??? def run( self ):
??????? print "starting====", self.name, time.ctime()
??????? time.sleep( 5 )
??????? print "end====", self.name, time.ctime(),
?
m = myThread( "m" )
m.setDaemon( True )
m.start()
print "main end"
print

輸出的結(jié)果為:starting====main end m Mon Aug 08 22:02:58 2011

可以看出,并沒(méi)有打印出子進(jìn)程m結(jié)束的時(shí)候本應(yīng)該打印的“end===…”

簡(jiǎn)單的線(xiàn)程同步

個(gè)執(zhí)行線(xiàn)程經(jīng)常要共享數(shù)據(jù),如果僅僅讀取共享數(shù)據(jù)還好,但是如果多個(gè)線(xiàn)程要修改共享數(shù)據(jù)的話(huà)就可能出現(xiàn)無(wú)法預(yù)料的結(jié)果。

假如兩個(gè)線(xiàn)程對(duì)象t1和t2都要對(duì)數(shù)值num=0進(jìn)行增1運(yùn)算,那么t1和t2都各對(duì)num修改10次的話(huà),那么num最終的結(jié)果應(yīng)該為20。但是如果當(dāng)t1取得num的值時(shí)(假如此時(shí)num為0),系統(tǒng)把t1調(diào)度為“sleeping”狀態(tài),而此時(shí)t2轉(zhuǎn)換為“running”狀態(tài),此時(shí)t2獲得的num的值也為0,然后他把num+1的值1賦給num。系統(tǒng)又把t2轉(zhuǎn)化為“sleeping”狀態(tài),t1為“running”狀態(tài),由于t1已經(jīng)得到num值為0,所以他也把num+1的值賦給了num為1。本來(lái)是2次增1運(yùn)行,結(jié)果卻是num只增了1次。類(lèi)似這樣的情況在多線(xiàn)程同時(shí)執(zhí)行的時(shí)候是有可能發(fā)生的。所以為了防止這類(lèi)情況的出現(xiàn)就要使用線(xiàn)程同步機(jī)制。

最簡(jiǎn)單的同步機(jī)制就是“鎖”

鎖對(duì)象用threading.RLock類(lèi)創(chuàng)建

復(fù)制代碼 代碼如下:
mylock = threading.RLock()

如何使用鎖來(lái)同步線(xiàn)程呢?線(xiàn)程可以使用鎖的acquire() (獲得)方法,這樣鎖就進(jìn)入“l(fā)ocked”狀態(tài)。每次只有一個(gè)線(xiàn)程可以獲得鎖。如果當(dāng)另一個(gè)線(xiàn)程試圖獲得這個(gè)鎖的時(shí)候,就會(huì)被系統(tǒng)變?yōu)椤癰locked”狀態(tài),直到那個(gè)擁有鎖的線(xiàn)程調(diào)用鎖的release() (釋放)方法,這樣鎖就會(huì)進(jìn)入“unlocked”狀態(tài)。“blocked”狀態(tài)的線(xiàn)程就會(huì)收到一個(gè)通知,并有權(quán)利獲得鎖。如果多個(gè)線(xiàn)程處于“blocked”狀態(tài),所有線(xiàn)程都會(huì)先解除“blocked”狀態(tài),然后系統(tǒng)選擇一個(gè)線(xiàn)程來(lái)獲得鎖,其他的線(xiàn)程繼續(xù)沉默(“blocked”)。

復(fù)制代碼 代碼如下:
import threading
mylock = threading.RLock()
class mythread(threading.Thread)
??? ...
??? def run(self ...):
??????? ...???? #此處 不可以 放置修改共享數(shù)據(jù)的代碼
??????? mylock.acquire()
??????? ...???? #此處 可以 放置修改共享數(shù)據(jù)的代碼
??????? mylock.release()
??????? ...???? #此處 不可以 放置修改共享數(shù)據(jù)的代碼

我們把修改共享數(shù)據(jù)的代碼稱(chēng)為“臨界區(qū)”,必須將所有“臨界區(qū)”都封閉在同一鎖對(duì)象的acquire()和release()方法調(diào)用之間。

鎖只能提供最基本的同步級(jí)別。有時(shí)需要更復(fù)雜的線(xiàn)程同步,例如只在發(fā)生某些事件時(shí)才訪(fǎng)問(wèn)一個(gè)臨界區(qū)(例如當(dāng)某個(gè)數(shù)值改變時(shí))。這就要使用“條件變量”。

條件變量用threading.Condition類(lèi)創(chuàng)建

復(fù)制代碼 代碼如下:
mycondition = threading.Condition()

條件變量是如何工作的呢?首先一個(gè)線(xiàn)程成功獲得一個(gè)條件變量后,調(diào)用此條件變量的wait()方法會(huì)導(dǎo)致這個(gè)線(xiàn)程釋放這個(gè)鎖,并進(jìn)入“blocked”狀態(tài),直到另一個(gè)線(xiàn)程調(diào)用同一個(gè)條件變量的notify()方法來(lái)喚醒那個(gè)進(jìn)入“blocked”狀態(tài)的線(xiàn)程。如果調(diào)用這個(gè)條件變量的notifyAll()方法的話(huà)就會(huì)喚醒所有的在等待的線(xiàn)程。

如果程序或者線(xiàn)程永遠(yuǎn)處于“blocked”狀態(tài)的話(huà),就會(huì)發(fā)生死鎖。所以如果使用了鎖、條件變量等同步機(jī)制的話(huà),一定要注意仔細(xì)檢查,防止死鎖情況的發(fā)生。對(duì)于可能產(chǎn)生異常的臨界區(qū)要使用異常處理機(jī)制中的finally子句來(lái)保證釋放鎖。等待一個(gè)條件變量的線(xiàn)程必須用notify()方法顯式的喚醒,否則就永遠(yuǎn)沉默。保證每一個(gè)wait()方法調(diào)用都有一個(gè)相對(duì)應(yīng)的notify()調(diào)用,當(dāng)然也可以調(diào)用notifyAll()方法以防萬(wàn)一。

同步隊(duì)列

我們經(jīng)常會(huì)采用生產(chǎn)者/消費(fèi)者關(guān)系的兩個(gè)線(xiàn)程來(lái)處理一個(gè)共享緩沖區(qū)的數(shù)據(jù)。例如一個(gè)生產(chǎn)者線(xiàn)程接受用戶(hù)數(shù)據(jù)放入一個(gè)共享緩沖區(qū)里,等待一個(gè)消費(fèi)者線(xiàn)程對(duì)數(shù)據(jù)取出處理。但是如果緩沖區(qū)的太小而生產(chǎn)者和消費(fèi)者兩個(gè)異步線(xiàn)程的速度不同時(shí),容易出現(xiàn)一個(gè)線(xiàn)程等待另一個(gè)情況。為了盡可能的縮短共享資源并以相同速度工作的各線(xiàn)程的等待時(shí)間,我們可以使用一個(gè)“隊(duì)列”來(lái)提供額外的緩沖區(qū)。

創(chuàng)建一個(gè)“隊(duì)列”對(duì)象,可以使用如下代碼:

復(fù)制代碼 代碼如下:
import Queue
myqueue = Queue.Queue(maxsize = 10)

Queue.Queue類(lèi)即是一個(gè)隊(duì)列的同步實(shí)現(xiàn)。隊(duì)列長(zhǎng)度可為無(wú)限或者有限。可通過(guò)Queue的構(gòu)造函數(shù)的可選參數(shù)maxsize來(lái)設(shè)定隊(duì)列長(zhǎng)度。如果maxsize小于1就表示隊(duì)列長(zhǎng)度無(wú)限。

將一個(gè)值放入隊(duì)列中:

myqueue.put(10)

調(diào)用隊(duì)列對(duì)象的put()方法在隊(duì)尾插入一個(gè)項(xiàng)目。put()有兩個(gè)參數(shù),第一個(gè)item為必需的,為插入項(xiàng)目的值;第二個(gè)block為可選參數(shù),默認(rèn)為1。如果隊(duì)列當(dāng)前為空且block為1,put()方法就使調(diào)用線(xiàn)程暫停,直到空出一個(gè)數(shù)據(jù)單元。如果block為0,put方法將引發(fā)Full異常。

將一個(gè)值從隊(duì)列中取出:

myqueue.get()

調(diào)用隊(duì)列對(duì)象的get()方法從隊(duì)頭刪除并返回一個(gè)項(xiàng)目。可選參數(shù)為block,默認(rèn)為1。如果隊(duì)列為空且block為1,get()就使調(diào)用線(xiàn)程暫停,直至有項(xiàng)目可用。如果block為0,隊(duì)列將引發(fā)Empty異常。

我們用一個(gè)例子來(lái)展示如何使用Queue:

復(fù)制代碼 代碼如下:
# queue_example.py
from Queue import Queue
import threading
import random
import time
?
# Producer thread
class Producer( threading.Thread ):
??? def __init__( self, threadname, queue ):
??????? threading.Thread.__init__( self, name = threadname )
??????? self.sharedata = queue
??? def run( self ):
??????? for i in range( 20 ):
??????????? print self.getName(), 'adding', i, 'to queue'
??????????? self.sharedata.put( i )
??????????? time.sleep( random.randrange( 10 ) / 10.0 )
??????????? print self.getName(), 'Finished'
?
# Consumer thread
class Consumer( threading.Thread ):
??? def __init__( self, threadname, queue ):
??????? threading.Thread.__init__( self, name = threadname )
??????? self.sharedata = queue
??? def run( self ):
??????? for i in range( 20 ):
??????????? print self.getName(), 'got a value:', self.sharedata.get()
??????????? time.sleep( random.randrange( 10 ) / 10.0 )
??????????? print self.getName(), 'Finished'
?
# Main thread
def main():
??? queue = Queue()
??? producer = Producer( 'Producer', queue )
??? consumer = Consumer( 'Consumer', queue )
?
??? print 'Starting threads ...'
??? producer.start()
??? consumer.start()
?
??? producer.join()
??? consumer.join()
?
??? print 'All threads have terminated.'
?
if __name__ == '__main__':
??? main()

程序輸出的結(jié)果為:

Starting threads ...

Producer adding 0 to queue

Consumer got a value: 0

Producer Finished

Producer adding 1 to queue

Producer Finished

Producer adding 2 to queue

Consumer Finished

Consumer got a value: 1

Consumer Finished

Consumer got a value: 2

Consumer Finished

Consumer got a value: Producer Finished

Producer adding 3 to queue

3

Consumer Finished

Consumer got a value: Producer Finished

Producer adding 4 to queue

4

ConsumerProducer Finished

?ConsumerFinished

got a value:Producer adding 5 to queue

5

Consumer Finished

Consumer got a value: Producer Finished

Producer adding 6 to queue

Producer Finished

Producer adding 7 to queue

6

Consumer Finished

Consumer got a value: 7

Producer Finished

Producer adding 8 to queue

Producer Finished

Producer adding 9 to queue

Consumer Finished

Consumer got a value: 8

ConsumerProducer? FinishedFinished

?

ConsumerProducer? got a value:adding 109

to queue

Producer Finished

Producer adding 11 to queue

Producer Finished

Producer adding 12 to queue

ConsumerProducer? FinishedFinished

?

ConsumerProducer? got a value:adding 1310

to queue

Producer Finished

Producer adding 14 to queue

Consumer Finished

Consumer got a value: 11

Producer Finished

Producer adding 15 to queue

Producer Finished

Producer adding 16 to queue

Producer Finished

Producer adding 17 to queue

Producer Finished

Producer adding 18 to queue

Consumer Finished

Consumer got a value: 12

Producer Finished

Producer adding 19 to queue

Producer Finished

Consumer Finished

Consumer got a value: 13

Consumer Finished

Consumer got a value: 14

Consumer Finished

Consumer got a value: 15

Consumer Finished

Consumer got a value: 16

Consumer Finished

Consumer got a value: 17

Consumer Finished

Consumer got a value: 18

Consumer Finished

Consumer got a value: 19

Consumer Finished

All threads have terminated.

希望本文所述對(duì)大家的Python程序設(shè)計(jì)有所幫助。


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 国产精品成人av | 特黄特色大片免费高清视频 | 秋霞电影免费理论久久 | 黄工厂精品视频在线观看 | 高清久久久久 | 在线观看亚洲专区 | 久久视频免费 | 久草在线资源视频 | 欧美日韩国产精品一区二区 | 日韩精品www| 精品无人乱码一区二区三区 | 蜜桃视频在线观看www社区 | 久久精品国产第一区二区 | 色综合色狠狠天天综合色 | 中国一级毛片在线视频 | 国产免费高清无需播放器 | 成人免费网视频 | www日韩免费高清视频 | 高清国语自产拍免费视频国产 | 欧美日韩中文在线 | 国产精品日日摸夜夜添夜夜av | 邪不压正免费观看完整高清视频 | 涩色婷婷狠狠第四四房社区奇米 | 青娱乐在线免费观看视频 | 亚洲精品成人av | 久久久伊人色综合A片无码 国产精品区一区二区三 | 久久精品中文 | 成人在线视频精品 | 黄色三级在线观看 | 天天夜夜骑 | 天天插天天干 | 精品一区二区久久久久久久网站 | 国产在线观看福利 | 毛片基地免费视频a | 免费香蕉视频 | 国产精品亲子伦av一区二区三区 | 国产精品香蕉 | 欧美日本中文 | 另类小说综合 | 欧美洲视频在线观看 | 久久精品视频在线观看 |