python-多線程等概念
阿新 • • 發佈:2018-05-21
opened pty 互斥鎖 set 執行 有意義 解釋 pass __main__
並發 & 並行
並發:是指系統具有處理多個任務的能力
並行:是指系統具有 同時 處理多個任務的能力
並行 是 並發的一個子集
同步 & 異步
同步:當進程執行到一個I/O(等待外部數據的時候)----------等 : 同步
異步: ----------不等,直到接收到數據再回來執行
GIL:全局解釋鎖
因為有GIL鎖,所以同一時刻,只有一個線程被CPU執行
任務:IO密集型
計算密集型
對於IO密集型:Python 的多線程是有意義的
可以采用多進程+協程
對於計算密集型:Python 的多線程就不推薦了,不適用了。
RLock(遞歸鎖)
說白了就是在一個大鎖中還要再包含子鎖
import threading,time def run1(): print("grab the first part data") lock.acquire() global num num +=1 lock.release() return num def run2(): print("grab the second part data") lock.acquire() global num2 num2+=1 lock.release()View Codereturn num2 def run3(): lock.acquire() res = run1() print(‘--------between run1 and run2-----‘) res2 = run2() lock.release() print(res,res2) if __name__ == ‘__main__‘: num,num2 = 0,0 lock = threading.RLock() for i in range(10): t = threading.Thread(target=run3) t.start()while threading.active_count() != 1: print(threading.active_count()) else: print(‘----all threads done---‘) print(num,num2)
Semaphore(信號量)
互斥鎖 同時只允許一個線程更改數據,而Semaphore是同時允許一定數量的線程更改數據 ,比如廁所有3個坑,那最多只允許3個人上廁所,後面的人只能等裏面有人出來了才能再進去。
import threading,time def run(n): semaphore.acquire() time.sleep(1) print("run the thread: %s\n" %n) semaphore.release() if __name__ == ‘__main__‘: num= 0 semaphore = threading.BoundedSemaphore(5) #最多允許5個線程同時運行 for i in range(20): t = threading.Thread(target=run,args=(i,)) t.start() while threading.active_count() != 1: pass #print threading.active_count() else: print(‘----all threads done---‘) print(num)View Code
Event
通過Event來實現兩個或多個線程間的交互,下面是一個紅綠燈的例子,即起動一個線程做交通指揮燈,生成幾個線程做車輛,車輛行駛按紅燈停,綠燈行的規則。
import threading,time import random def light(): if not event.isSet(): event.set() #wait就不阻塞 #綠燈狀態 count = 0 while True: if count < 10: print(‘\033[42;1m--green light on---\033[0m‘) elif count <13: print(‘\033[43;1m--yellow light on---\033[0m‘) elif count <20: if event.isSet(): event.clear() print(‘\033[41;1m--red light on---\033[0m‘) else: count = 0 event.set() #打開綠燈 time.sleep(1) count +=1 def car(n): while 1: time.sleep(random.randrange(10)) if event.isSet(): #綠燈 print("car [%s] is running.." % n) else: print("car [%s] is waiting for the red light.." %n) if __name__ == ‘__main__‘: event = threading.Event() Light = threading.Thread(target=light) Light.start() for i in range(3): t = threading.Thread(target=car,args=(i,)) t.start()View Code
隊列queue (重點)
1,queue.Queue() FIFO隊列-先進先出
2,queue.LifoQueue() LIFO隊列,先進後出
3,queue.PriorityQueue() 按照優先級,越低越先出
方法:
q.size 返回隊列大小
q.empty() 如果隊列為空返回true
q.full() 如果隊列為滿返回true
q.get () 裏面可以設置block 的t,f
q.put()
q.join()實際是隊列為空時再執行別的操作
python-多線程等概念