国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - python多線程用法實例詳解

python多線程用法實例詳解

2020-05-19 09:13腳本之家 Python

這篇文章主要介紹了python多線程用法,以實例形式較為詳細的分析了線程同步、隊列等概念及用法技巧,需要的朋友可以參考下

本文實例分析了python多線程用法。分享給大家供大家參考。具體如下:

今天在學習嘗試學習python多線程的時候,突然發現自己一直對super的用法不是很清楚,所以先總結一些遇到的問題。當我嘗試編寫下面的代碼的時候:

 

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


出現:

 

super( B, self ).__init__()

TypeError: must be type, not classobj

最后發現原來是python中的新式類的問題,也就是A必須是新式類。解決方法如下兩種:

(1)

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

 

(2)

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


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

 

語句中添加self,也就是super( B, self ).__init__( self ),會出現如下的錯誤:

    super( B, self ).__init__( self )

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

以上只是一點點本人的心得筆記,呵呵。

復制代碼 代碼如下:
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()


輸出的結果:

 

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

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

如果一個進程的主線程運行完畢而子線程還在執行的話,那么進程就不會退出,直到所有子線程結束為止。比如下面的例子:

復制代碼 代碼如下:
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


輸出的結果為:

 

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

main end

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

也就是主進程結束之后,子進程還沒有結束

如果我們想在主進程結束的時候,子進程也結束的話,我們就應該使用setDaemon()函數。

實例如下:

復制代碼 代碼如下:
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


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

 

可以看出,并沒有打印出子進程m結束的時候本應該打印的“end===…”

簡單的線程同步

個執行線程經常要共享數據,如果僅僅讀取共享數據還好,但是如果多個線程要修改共享數據的話就可能出現無法預料的結果。

假如兩個線程對象t1和t2都要對數值num=0進行增1運算,那么t1和t2都各對num修改10次的話,那么num最終的結果應該為20。但是如果當t1取得num的值時(假如此時num為0),系統把t1調度為“sleeping”狀態,而此時t2轉換為“running”狀態,此時t2獲得的num的值也為0,然后他把num+1的值1賦給num。系統又把t2轉化為“sleeping”狀態,t1為“running”狀態,由于t1已經得到num值為0,所以他也把num+1的值賦給了num為1。本來是2次增1運行,結果卻是num只增了1次。類似這樣的情況在多線程同時執行的時候是有可能發生的。所以為了防止這類情況的出現就要使用線程同步機制。

最簡單的同步機制就是“鎖”

鎖對象用threading.RLock類創建

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

 

如何使用鎖來同步線程呢?線程可以使用鎖的acquire() (獲得)方法,這樣鎖就進入“locked”狀態。每次只有一個線程可以獲得鎖。如果當另一個線程試圖獲得這個鎖的時候,就會被系統變為“blocked”狀態,直到那個擁有鎖的線程調用鎖的release() (釋放)方法,這樣鎖就會進入“unlocked”狀態。“blocked”狀態的線程就會收到一個通知,并有權利獲得鎖。如果多個線程處于“blocked”狀態,所有線程都會先解除“blocked”狀態,然后系統選擇一個線程來獲得鎖,其他的線程繼續沉默(“blocked”)。

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

 

我們把修改共享數據的代碼稱為“臨界區”,必須將所有“臨界區”都封閉在同一鎖對象的acquire()和release()方法調用之間。

鎖只能提供最基本的同步級別。有時需要更復雜的線程同步,例如只在發生某些事件時才訪問一個臨界區(例如當某個數值改變時)。這就要使用“條件變量”。

條件變量用threading.Condition類創建

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

 

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

如果程序或者線程永遠處于“blocked”狀態的話,就會發生死鎖。所以如果使用了鎖、條件變量等同步機制的話,一定要注意仔細檢查,防止死鎖情況的發生。對于可能產生異常的臨界區要使用異常處理機制中的finally子句來保證釋放鎖。等待一個條件變量的線程必須用notify()方法顯式的喚醒,否則就永遠沉默。保證每一個wait()方法調用都有一個相對應的notify()調用,當然也可以調用notifyAll()方法以防萬一。

同步隊列

我們經常會采用生產者/消費者關系的兩個線程來處理一個共享緩沖區的數據。例如一個生產者線程接受用戶數據放入一個共享緩沖區里,等待一個消費者線程對數據取出處理。但是如果緩沖區的太小而生產者和消費者兩個異步線程的速度不同時,容易出現一個線程等待另一個情況。為了盡可能的縮短共享資源并以相同速度工作的各線程的等待時間,我們可以使用一個“隊列”來提供額外的緩沖區。

創建一個“隊列”對象,可以使用如下代碼:

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


Queue.Queue類即是一個隊列的同步實現。隊列長度可為無限或者有限。可通過Queue的構造函數的可選參數maxsize來設定隊列長度。如果maxsize小于1就表示隊列長度無限。

 

將一個值放入隊列中:

myqueue.put(10)

調用隊列對象的put()方法在隊尾插入一個項目。put()有兩個參數,第一個item為必需的,為插入項目的值;第二個block為可選參數,默認為1。如果隊列當前為空且block為1,put()方法就使調用線程暫停,直到空出一個數據單元。如果block為0,put方法將引發Full異常。

將一個值從隊列中取出:

myqueue.get()

調用隊列對象的get()方法從隊頭刪除并返回一個項目。可選參數為block,默認為1。如果隊列為空且block為1,get()就使調用線程暫停,直至有項目可用。如果block為0,隊列將引發Empty異常。

我們用一個例子來展示如何使用Queue:

復制代碼 代碼如下:
# 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()


程序輸出的結果為:

 

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.

希望本文所述對大家的Python程序設計有所幫助。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 精品中文字幕一区二区 | 青娱乐一区 | 九色 在线 | 精品在线二区 | 羞羞网站 | 午夜精品网站 | 国产精品久久久久白丝呻吟 | 一二三区字幕免费观看av | 日韩欧美国产精品 | 天天艹久久 | 国产精品无码久久久久 | 视频在线一区 | 久久99精品国产麻豆婷婷洗澡 | 中文字幕一区二区三区四区不卡 | 三区在线视频 | 欧美日韩精品久久久 | 国产在线观看一区二区 | 黄色大片网站 | www.色.com| 91欧美视频在线 | 日韩午夜影院 | 午夜爱爱毛片xxxx视频免费看 | 久久99精品久久久久久6194 | 中文字幕一区二区三区乱码图片 | 中文在线视频 | 精品久久97 | 欧美日韩精品久久久免费观看 | 激情欧美一区二区三区中文字幕 | 国产黄色在线观看 | 国产精品日韩一区二区 | 俺来也俺也啪www色 性色视频在线 | 久久综合九色综合欧美狠狠 | 日韩三级 | 成人网av | 人人爱人人射 | 国产欧美日韩二区 | 九九亚洲| 日韩有码av | 欧美国产另类 | 国产日韩精品一区 | 色播视频网站 |