python 并发编程 同步调用和异步调用 回调函数

提交任务的两张方式:

1.同步调用

2.异步调用

同步调用:提交完任务后,就在原地等待任务执行完后,拿到结果,再执行下一行代码

同步调用,导致程序串行执行

from concurrent.futures import ThreadPoolExecutor
import time
import random


def la(name):
    print("%s is 正在拉" % name)
    time.sleep(random.randint(1,3))
    res = random.randint(1,10) * "#"
    return {"name":name,"res":res}

def weigh(shit):
    name = shit["name"]
    size = len(shit["res"])
    print("%s 拉了《%s》kg" %(name,size))

if __name__ == "__main__":
    pool = ThreadPoolExecutor(13)

    shit1 = pool.submit(la,"mike").result()
    weigh(shit1)
    shit2 = pool.submit(la,"peter").result()
    weigh(shit2)
    shit3 = pool.submit(la,"jack").result()
    weigh(shit3)

'''
mike is 正在拉
mike 拉了《2》kg
peter is 正在拉
peter 拉了《9》kg
jack is 正在拉
jack 拉了《4》kg
'''

异步调用:提交完任务后,不再原地等待任务执行完

from concurrent.futures import ThreadPoolExecutor
import time
import random


def la(name):
    print("%s is 正在拉" % name)
    time.sleep(random.randint(1,3))
    res = random.randint(1,10) * "#"
    return weigh({"name":name,"res":res})

def weigh(shit):
    name = shit["name"]
    size = len(shit["res"])
    print("%s 拉了《%s》kg" %(name,size))

if __name__ == "__main__":
    pool = ThreadPoolExecutor(13)

    pool.submit(la,"mike")
    pool.submit(la,"peter")
    pool.submit(la,"jack")

'''
mike is 正在拉
peter is 正在拉
jack is 正在拉
mike 拉了《3》kg
jack 拉了《8》kg
peter 拉了《1》kg
'''

回调函数

可以为进程池或线程池内的每个进程或线程绑定一个函数,该函数在进程或线程的任务执行完毕后自动触发,并接收任务对象的返回值当作参数传给绑定的函数,该函数称为回调函数

add_done_callback() 
传的是要绑定的函数,还要在函数,func拿到的是一个future对象obj,需要用obj.result()拿到结果
 
from concurrent.futures import ThreadPoolExecutor
import time
import random


def la(name):
    print("%s is 正在拉" % name)
    time.sleep(random.randint(1,3))
    res = random.randint(1,10) * "#"
    return {"name": name, "res": res}

def weigh(shit):
    shit = shit.result()
    name = shit["name"]
    size = len(shit["res"])
    print("%s 拉了《%s》kg" %(name,size))

if __name__ == "__main__":
    pool = ThreadPoolExecutor(13)

    pool.submit(la,"mike").add_done_callback(weigh)
    pool.submit(la,"peter").add_done_callback(weigh)
    pool.submit(la,"jack").add_done_callback(weigh)

同步调用就是阻塞?

同步和阻塞没有关系,同步调用只是一种提交任务方式,同步提交完任务后,不管程序是计算密集型还是io密集型程序,它都会原地等待任务执行。

原文地址:https://www.cnblogs.com/mingerlcm/p/11143686.html