GIL,queue,進程池與線程池

GILpython

1.什麼是GIL(這是Cpython解釋器)安全

         GIL本質就是一把互斥鎖,既然是互斥鎖,原理都是同樣的,都是讓多個併發線程同一時間只能有一個執行多線程

         即:有了GIL的存在,同一進程內的多個線程同一時刻只能有一個在運行,意味着Cpython中一個進程下的多個線程沒法實現並行,因此就沒法利用多核優點,但不影響併發的實現併發

         GIL能夠被比喻成執行權限,同一進程下的全部線程,想要執行都須要先搶執行權限dom

 

2.爲什麼要有GIL異步

         由於Cpython解釋器自帶垃圾回收機制不是線程安全的函數

 

3.如何用spa

         GIL vs 自定義互斥鎖線程

                  GIL至關於執行權限,會在任務沒法執行的狀況下,被強行釋放code

                  自定義互斥鎖即使是沒法執行,也不會自動釋放

 

4.有兩種併發解決方案:

         多進程:計算密集型

         多線程:IO密集型

 

線程queue

#1.隊列:先進先出
q=queue.Queue(3)
q.put(1)
q.put(2)
q.put(3)

print(q.get())
print(q.get())
print(q.get())

#2.堆棧:先進後出
q=queue.LifoQueue()
q.put(1)
q.put(2)
q.put(3)
print(q.get())
print(q.get())
print(q.get())

#3. 優先級隊列:優先級高先出來,數字越小,優先級越高
q=queue.PriorityQueue()
q.put((3,'data1'))
q.put((-10,'data2'))
q.put((11,'data3'))

print(q.get())
print(q.get())
print(q.get())

進程池與線程池

1.何時用池

         池的功能是限制啓動的進程或線程數

         何時應該限制?

                  當併發的任務數遠遠超過了計算機的承受能力時,即沒法一次性開啓過多的進程數或線程數時,就應該使用池的概念,將開啓的進程數或線程數限制在計算機可承受的範圍內。

 

2.同步vs異步

         同步、異步指的是提交任務的兩種方式

         同步:提交任務後就在原地等待,直到任務運行完畢後拿到任務的返回值,再繼續運行下一行代碼

         異步:提交完任務(綁定一個回調函數)後根本就不在原地等待,直接運行下一行代碼,等到任務有返回值後會自動觸發回調函數

 

from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
import os,time,random 

def task(n):
    print('%s run...' %os.getpid())
    time.sleep(5)
    return n**2

def parse(future):
    time.sleep(1)
    res=future.result()
    print('%s 處理了 %s' %(os.getpid(),res))

if __name__ == '__main__':
    pool=ProcessPoolExecutor(4)
    start=time.time()
    for i in range(1,5):
        future=pool.submit(task,i)
        future.add_done_callback(parse) # parse會在futrue有返回值時馬上觸發,而且將future看成參數傳給parse
    pool.shutdown(wait=True)
    stop=time.time()
    print('',os.getpid(),(stop - start))

線程池只須要將pool=ProcessPoolExecutor(4)改爲pool = ThreadPoolExecutor(4)便可,在使用回調時,多進程是用主進程來執行回調的,而多線程是哪一個線程閒着就由哪一個線程來執行

相關文章
相關標籤/搜索