day32-3 阻塞\非阻塞\同步\異步&異步回調

阻塞\非阻塞\同步\異步&異步回調

阻塞與非阻塞是用來描述程序的狀態python

阻塞:指調用結果返回以前,當前線程會被掛起(如遇到IO操做),函數只有在獲得結果以後纔會將阻塞的線程激活多線程

非阻塞:指不能馬上獲得返回結果以前也會馬上返回,同時不會阻塞當前線程併發

 

串行、併發與並行是用來描述處理任務的方式異步

串行:程序按照自上而下的順序執行函數

併發:多個任務同時執行,本質上是在不一樣進程或線程間切換執行,因爲速度快因此感受是同時運行spa

並行:真正意義上的多個任務同時執行線程

 

同步與異步是指提交任務的方式code

同步:指的是提交任務後必須在原地等待,直到任務結束。此時任務仍是激活的狀態,因此並非阻塞進程

異步:指的是提交任務後不須要在原地等待,能夠繼續往下執行代碼。例如開啓多線程多進程能夠實現異步,會產生阻塞ip

 

異步效率會高於同步效率,但異步任務將致使一個問題:任務的發起方不知道任務什麼時候結束。因此有如下兩種解決方法:

方法一:重複的隔一段時間就詢問一次。效率低,而且沒法及時獲取結果,因此不推薦使用

方法二:讓任務的執行方主動通知(異步回調)。能夠及時拿到任務的結果,推薦使用

  • 異步回調就是在發起任務時給任務綁定一個函數,在任務執行完後自動調用這個函數,把結果傳給發起方(若發起方不關心任務結果,就不須要異步回調)

異步回調使用

# 線程中異步回調
import time
from threading import Thread


def task(callback):
    print('task start....')
    sum = 0
    for i in range(10000):
        sum += i
    time.sleep(2)
    callback(sum)


# 回調函數,參數爲任務的結果
def callback(res):
    print('task result:', res)


t = Thread(target=task, args=(callback,))
t.start()
print('over')
--------------------------------------------------------------------------------------


# 進程異步回調
import time
from multiprocessing import Process


def task(callback):
    print('task start....')
    sum = 0
    for i in range(10000):
        sum += i
    time.sleep(2)
    callback(sum)


def callback(res):
    print('task result:', res)


if __name__ == '__main__':
    p = Process(target=task,args=(callback,))
    p.start()
    print('over')

進程池&線程池的異步回調

# 線程池異步回調
import time
from concurrent.futures import ThreadPoolExecutor


def task(num):
    print('task starting...')
    sum = 0
    for i in range(1000):
        sum += i
    time.sleep(2)
    print(num)
    return sum


def callback(obj):
    print('task end:', obj.result())


pool = ThreadPoolExecutor(2)
res = pool.submit(task, 123)
res.add_done_callback(callback)  爲任務綁定回調函數
print('over')
--------------------------------------------------------------------------------------

# 進程池異步回調
import time
from concurrent.futures import ProcessPoolExecutor


def task():
    print('task start....')
    time.sleep(2)
    print('task end')
    return 'hello python'


def callback(res):
    print('任務結果:', res.result())


if __name__ == '__main__':
    p = ProcessPoolExecutor(2)
    res = p.submit(task)
    res.add_done_callback(callback)  # 爲任務綁定回調函數
    print('over')
    
# 補充知識:
# res: <Future at 0x21d2230a9b0 state=running>
# res.result: <bound method Future.result of <Future at 0x21d2230a9b0 state=running>>
# res.result(): hello python
相關文章
相關標籤/搜索