標籤:使用 io 資料 for art ar cti div
一)線程基礎
1、建立線程:
thread模組提供了start_new_thread函數,用以建立線程。start_new_thread函數成功建立後還能夠對其進行操作。
其函數原型:
start_new_thread(function,atgs[,kwargs])
其參數含義例如以下:
function: 線上程中啟動並執行函數名
args:元組形式的參數列表。
kwargs: 可選參數,以字典的形式指定參數
方法一:通過使用thread模組中的函數建立新線程。
>>> import thread>>> def run(n):for i in range(n):print i>>> thread.start_new_thread(run,(4,)) #注意第二個參數一定要是元組的形式538401>>> 23KeyboardInterrupt>>> thread.start_new_thread(run,(2,))178401>>> thread.start_new_thread(run,(),{‘n‘:4})397201>>> 23thread.start_new_thread(run,(),{‘n‘:3})324801>>> 2
方法二:通過繼承threading.Thread建立線程
>>> import threading>>> class mythread(threading.Thread):def __init__(self,num):threading.Thread.__init__(self)self.num = numdef run(self): #重載run方法print ‘I am‘, self.num>>> t1 = mythread(1)>>> t2 = mythread(2)>>> t3 = mythread(3)>>> t1.start() #執行線程t1I am>>> 1t2.start()I am>>> 2t3.start()I am>>> 3
方法三:使用threading.Thread直接線上程中執行函數。
import threading>>> def run(x,y):for i in range(x,y):print i>>> t1 = threading.Thread(target=run,args=(15,20)) #直接使用Thread增益集函數args為函數參數>>> t1.start()15>>> 16171819
二)Thread對象中的經常用法:
1、isAlive方法:
>>> import threading>>> import time>>> class mythread(threading.Thread):def __init__(self,id):threading.Thread.__init__(self)self.id = iddef run(self):time.sleep(5) #休眠5秒print self.id>>> t = mythread(1)>>> def func():t.start()print t.isAlive() #列印線程狀態>>> func()True>>> 1
2、join方法:
原型:join([timeout])
timeout: 可選參數,線程執行的最長時間
import threading>>> import time #匯入time模組>>> class Mythread(threading.Thread):def __init__(self,id):threading.Thread.__init__(self)self.id = iddef run(self):x = 0time.sleep(20)print self.id>>> def func():t.start()for i in range(5):print i>>> t = Mythread(2)>>> func()01234>>> 2def func():t.start()t.join()for i in range(5):print i>>> t = Mythread(3)>>> func()301234>>>
3、線程名:
>>> import threading>>> class mythread(threading.Thread):def __init__(self,threadname):threading.Thread.__init__(self,name=threadname)def run(self):print self.getName()>>> >>> t1 = mythread(‘t1‘)>>> t1.start()t1>>>
4、setDaemon方法
在指令碼執行的過程中有一個主線程,假設主線程又建立了一個子線程,那麼當主線程退出時,會檢驗子線程是否完畢。假設子線程未完畢,則主線程會在等待子線程完畢後退出。
當須要主線程退出時,無論子線程是否完畢都隨主線程退出,則能夠使用Thread對象的setDaemon方法來設定。
三)線程同步
1.簡單的線程同步
使用Thread對象的Lock和RLock能夠實現簡單的線程同步。對於假設須要每次僅僅有一個線程操作的資料,能夠將操作過程放在acquire方法和release方法之間。如:
# -*- coding:utf-8 -*-import threadingimport timeclass mythread(threading.Thread):def __init__(self,threadname):threading.Thread.__init__(self,name = threadname)def run(self):global x #設定全域變數#lock.acquire() #調用lock的acquire方法for i in range(3):x = x + 1time.sleep(2)print x#lock.release() #調用lock的release方法#lock = threading.RLock() #產生Rlock對象t1 = []for i in range(10):t = mythread(str(i))t1.append(t)x = 0 #將全域變數的值設為0for i in t1: i.start()E:/study/python/workspace>xianchengtongbu.py36912151821242730
假設將lock.acquire()和lock.release(),lock = threading.Lock()刪除後儲存執行指令碼,結果將是輸出10個30。30是x的終於值,因為x是全域變數,每一個線程對其操作後進入休眠狀態,線上程休眠的時候,python解譯器就執行了其它的線程而是x的值添加。當全部線程休眠結束後,x的值已被全部線改動為了30,因此輸出全部為30。
2、使用條件變數保持線程同步。
Python的Condition對象提供了對複製線程同步的支援。使用Condition對象能夠在某些事件觸發後才處理資料。Condition對象除了具有acquire方法和release的方法外,還有wait方法、notify方法、notifyAll方法等用於條件處理。
# -*- coding:utf-8 -*-import threadingclass Producer(threading.Thread):def __init__(self,threadname):threading.Thread.__init__(self,name = threadname)def run(self):global xcon.acquire()if x == 1000000:con.wait()#passelse:for i in range(1000000):x = x + 1con.notify()print xcon.release()class Consumer(threading.Thread):def __init__(self,threadname):threading.Thread.__init__(self,name = threadname)def run(self):global x con.acquire()if x == 0:con.wait()#passelse:for i in range(1000000):x = x - 1con.notify()print x con.release()con = threading.Condition()x = 0p = Producer(‘Producer‘)c = Consumer(‘Consumer‘)p.start()c.start()p.join()c.join()print xE:/study/python/workspace>xianchengtongbu2.py100000000
線程間通訊:
Event對象用於線程間的相互連信。他提供了設定訊號、清除信宏、等待等用於實現線程間的通訊。
1、設定訊號。Event對象使用了set()方法後,isSet()方法返回真。
2、清除訊號。使用Event對象的clear()方法後,isSet()方法返回為假。
3、等待。當Event對象的內部訊號標誌為假時,則wait()方法一直等到其為真時才返回。還能夠向wait傳遞參數,設定最長的等待時間。
# -*- coding:utf-8 -*-import threadingclass mythread(threading.Thread):def __init__(self,threadname):threading.Thread.__init__(self,name = threadname)def run(self):global eventif event.isSet():event.clear()event.wait() #當event被標記時才返回print self.getName()else:print self.getName()event.set()event = threading.Event()event.set()t1 = []for i in range(10):t = mythread(str(i))t1.append(t)for i in t1:i.start()