day32-3 阻塞\非阻塞\同步\异步&异步回调

阻塞\非阻塞\同步\异步&异步回调

阻塞与非阻塞是用来描述程序的状态

阻塞:指调用结果返回之前,当前线程会被挂起(如遇到IO操作),函数只有在得到结果之后才会将阻塞的线程激活

非阻塞:指不能立刻得到返回结果之前也会立刻返回,同时不会阻塞当前线程

 

串行、并发与并行是用来描述处理任务的方式

串行:程序按照自上而下的顺序执行

并发:多个任务同时执行,本质上是在不同进程或线程间切换执行,由于速度快所以感觉是同时运行

并行:真正意义上的多个任务同时执行

 

同步与异步是指提交任务的方式

同步:指的是提交任务后必须在原地等待,直到任务结束。此时任务还是激活的状态,所以并不是阻塞

异步:指的是提交任务后不需要在原地等待,可以继续往下执行代码。例如开启多线程多进程可以实现异步,会产生阻塞

 

异步效率会高于同步效率,但异步任务将导致一个问题:任务的发起方不知道任务何时结束。所以有以下两种解决方法:

方法一:重复的隔一段时间就询问一次。效率低,并且无法及时获取结果,所以不推荐使用

方法二:让任务的执行方主动通知(异步回调)。可以及时拿到任务的结果,推荐使用

  • 异步回调就是在发起任务时给任务绑定一个函数,在任务执行完后自动调用这个函数,把结果传给发起方(若发起方不关心任务结果,就不需要异步回调)

异步回调使用

# 线程中异步回调
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
posted @ 2019-07-07 16:20  Never&say&die  阅读(170)  评论(0编辑  收藏  举报