首頁  >  文章  >  後端開發  >  python 線程實踐

python 線程實踐

巴扎黑
巴扎黑原創
2016-12-09 10:42:441292瀏覽

"""" Python中使用線程有兩種方式:函數或用類別來包裝線程物件。 

1、  函數式:呼叫thread模組中的start_new_thread()函數來產生新執行緒。執行緒的結束可以等待執行緒自然結束,也可以在執行緒函數中呼叫thread.exit()或thread.exit_thread()方法。
import time 
import thread 

def timer(no,interval): 
  cnt=0 
  
  while cnt    cnt= cnt+1 
  

def test(): 
  thread.start_new_thread(timer,(1,1)) 
  thread.start_new_thread==(timer,(2,2)) 
  thread.start_new_thread==(timer,(2,2)) 
  thread.startname thread starting' 
  test() 
  time.sleep(20) 
  thread.exit_thread() 
  print 'exit...' 
2、  建立一個建立一個子類別的子類別,Threadthread?使用: 

1,在自己的線程類別的__init__裡調用threading.Thread.__init__(self, name = threadname) 

Threadname為線程的名字 

2, run(),通常需要重寫,寫程式碼實現做需要的功能。

3,getName(),取得執行緒物件名稱 

4,setName(),設定執行緒物件名稱 

5,start(),啟動執行緒 

6,jion([timeout]),等待另一個執行緒結束後再運行。 

7,setDaemon(bool),設定子執行緒是否隨主執行緒一起結束,必須在start()之前呼叫。預設為False。 

8,isDaemon(),判斷執行緒是否隨主執行緒一起結束。 

9,isAlive(),檢查執行緒是否在運作中。
import threading 
import time 

class timer(threading.Thread): 
  def __init__(self,num,interval):  sel.
    self.interval=interval 
    self .thread_stop=False 

  def run(self): 
    while not self.thread_stop: 
         time.sleep( self.interval) 

  def stop(self): 
    self.thread_stop=True 

def test():  我() 
thread2.start() 
  time.sleep(10) 
  thread1.stop() 
  thread2.stop() 
  return 

if __name__=='main: 
問題產生的原因是沒有控制多個執行緒對相同資源的訪問,對資料造成破壞,使得執行緒運行的結果不可預期。這種現象稱為「線程不安全」。
import threading 
import time 

class MyThread(threading.Thread): 
  def run(self): 
    sg='I am '+ self.getName ()+'@'+str(i) 
      print msg 

def test(): 
  for i in range(5): 
    __Thread() ': 
  test() 

上面的範例引出了多執行緒程式設計最常見的問題:資料共享。當多個執行緒都修改某一個共享資料的時候,就需要進行同步控制。 

執行緒同步能夠確保多個執行緒安全存取競爭資源,最簡單的同步機制是引入互斥鎖。互斥鎖為資源引入一個狀態:鎖定/非鎖定。某個執行緒要更改共享資料時,先將其鎖定,此時資源的狀態為“鎖定”,其他執行緒不能更改;直到該執行緒釋放資源,將資源的狀態變成“非鎖定”,其他的執行緒才能再次鎖定該資源。互斥鎖保證了每次只有一個執行緒進行寫入操作,從而保證了多執行緒情況下資料的正確性。其中,鎖定方法acquire可以有一個超時時間的可選參數timeout。如果設定了timeout,則在逾時後透過回傳值可以判斷是否得到了鎖,從而可以進行一些其他的處理 

threading模組中定義了Lock類 
import threading 
import time 

class MyThread(threading.Thread ): 
  def run(self): 
global num 
    time.sleep(1) 

    if mutex.acquire(): 
     num=num+1 
      mutex.release() 
num=0 
mutex=threading.Lock() 

def test(): 
  for i in range(5): 
    t=MyThread() 🠎 test() 
""" 
"""更簡單的死鎖情況是一個執行緒「迭代」請求相同資源,直接就會造成死鎖: 
import threading 
import time 

class MyThread(threading.Thread)(threading.Thread) : 
    def run(self): 
        global num 
                   num = num+1 
            msg = self.name+' set num to '+str(num)
            print msg 
            mutex.acquire()      mutex.release() 
num = 0 
mutex = threading.Lock() 
def test(): 
    for i in range(5): 🠎 = MyThread() 
        t.start() 
if __name__ == '__main__': 
    test() 
為了支援在同一執行緒中多次要求相同資源,python」提供了「可重複鎖定了. RLock內部維護一個Lock和一個counter變量,counter記錄了acquire的次數,從而使得資源可以被多次require。直到一個線程所有的acquire都被release,其他的線程才能獲得資源。上述的例子如果使用RLock代替Lock,則不會發生死鎖: 
import threading 
import time 

class MyThread(threading.Thread): 
    def run(self):     time.sleep(1) 

        if mutex.acquire(1):  
           (1):                print msg 
            mutex.acquire() 
    mutex.release () 
num = 0 
mutex = threading.RLock() 
def test(): 
    for i in range(5): 
    __name__ == '__main__':
    test() 
""" 

""" 
python多執行緒程式設計(5): 條件變數同步 

互斥鎖定是最簡單的執行緒同步問題的支持。 Condition被稱為條件變量,除了提供與Lock類似的acquire和release方法外,還提供了wait和notify方法。線程先acquire一個條件變量,然後再判斷一些條件。如果條件不滿足則wait;如果條件滿足,進行一些處理改變條件後,透過notify方法通知其他線程,其他處於wait狀態的線程接到通知後會重新判斷條件。不斷的重複這個過程,從而解決複雜的同步問題。 

可以認為Condition物件維護了一個鎖定(Lock/RLock)和一個waiting池。執行緒透過acquire取得Condition對象,當呼叫wait方法時,執行緒會釋放Condition內部的鎖定並進入blocked狀態,同時在waiting池中記錄這個執行緒。當呼叫notify方法時,Condition物件會從waiting池中挑選一個線程,通知其呼叫acquire方法嘗試取到鎖。 

Condition物件的建構子可以接受一個Lock/RLock物件作為參數,如果沒有指定,則Condition物件會在內部自行建立一個RLock。 

除了notify方法外,Condition物件還提供了notifyAll方法,可以通知waiting池中的所有執行緒嘗試acquire內部鎖定。由於上述機制,處於waiting狀態的執行緒只能透過notify方法喚醒,所以notifyAll的作用在於防止有執行緒永遠處於沉默狀態。 

簡報條件變數同步的經典問題是生產者與消費者問題:假設有一群生產者(Producer)和一群消費者(Consumer)透過一個市場來互動產品。生產者的」策略「是如果市場上剩餘的產品少於1000個,那麼就生產100個產品放到市場上;而消費者的」策略「是如果市場上剩餘產品的數量多餘100個,那麼就消費3個產品。使用Condition解決生產者與消費者問題的代碼如下: 
import threading 
import time 

class Producer(threading.Thread): 
    if con.acquire() : 
        if count>1000: 
          con.wait() 
    
          print self.name+' produce 100,count='+str(count) 

       (1) 

class Customer(threading.Thread): 
  def run(self): 
    global count 
    count>100: 
          count=count-100 
          print self .name+ 'consume 100, count='+str(count) 
        else: 
         time.sleep(1) 

count=500 
con=threading.Condition() 

def test(): 
  for i in range(5): 
    p=Producer() 
    p.start() 
   

if __name__==' __main__': 
  test() 
python中預設全域變數在函數中可以讀,但是不能寫但是 
對con只讀,所以不用global引入"""

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn