1. 程式人生 > >python-多線程等概念

python-多線程等概念

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()
    
return 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)
View Code

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-多線程等概念