admin管理员组

文章数量:1581289

以下整理一下操作系统中的同步、异步、阻塞和非阻塞之间的关系和异同点,并附部分代码解释。

一、同步与异步

【同步简述】:当发出一个“调用”时,在没有得到结果之前,该“调用”就不返回,“调用者”需一直等待该“调用”结束,才能进行下一步工作。
【特点】:调用方主动等待
【举例】:假设你给隔壁老王打电话,要他家Wifi密码,老王说他要找一下。这时你没有挂电话,而是一直等待另一头的老王找了半天,直到等待他把Wifi密码找到告诉你(返回一个结果)后,你才挂了电话去切菜。以下是Python代码演示同步程序:

# 普通同步代码实现多个任务
import time
def task_1():
    print('给老王打电话问他要Wifi密码...')
    time.sleep(3)  # 假设老王找密码耗时3s
    print('老王找到密码并告知,耗时3s')
def task_2():
    print('你开始切菜...')
    time.sleep(2)  # 假设你切菜耗时2s
    print('你切完菜,耗时耗时2s')

start = time.time()
task_1()
task_2()
print('所有任务总耗时%.5f秒' % float(time.time()-start))

执行结果如下:

给老王打电话问他要Wifi密码...
老王找到密码并告知,耗时3s
你开始切菜...
你切完菜,耗时耗时2s
所有任务总耗时5.00574

【异步简述】:“调用”在发出之后,就直接返回了,也就没有返回结果。“被调用者”完成任务后,通过状态来通知“调用者”继续回来处理该“调用”。
【特点】:调用方被动等待
【举例】依然是上面的案例,你给隔壁老王打电话,要他家Wifi密码,老王说他要找一下。这时你说让他慢慢找,等找到后在给你打电话告知,于是你便变挂了电话去切菜。以下是Python调用asyncio库实现异步:

import time
import asyncio

async def task_1():
    print('给老王打电话问他要Wifi密码......')
    await asyncio.sleep(3)  # 假设耗时3s
    print('老王找到密码并告知,耗时3s')

async def task_2():
    print('你开始切菜...')
    await asyncio.sleep(2)  # 假设耗时2s
    print('你切完菜,耗时2s')

async def main(): # 调用方
    tasks = [task_2(), task_1()]  # 把所有任务添加到task中
    await asyncio.wait(tasks) # 子生成器


if __name__ == '__main__':
    start = time.time()
    loop = asyncio.get_event_loop() # 创建一个事件循环对象loop
    try:
        loop.run_until_complete(main()) # 完成事件循环,直到最后一个任务结束
    finally:
        loop.close() # 结束事件循环
    print('所有任务总耗时%.5f秒' % float(time.time()-start))

执行结果如下:

给老王打电话问他要Wifi密码......
你开始切菜...
你切完菜,耗时2s
老王找到密码并告知,耗时3s
所有任务总耗时3.00673

【总结】:同步与异步更关注的是消息通信机制,说白了就是通信方式。同步是主动等待式通信,异步是被动等待式通信。

二、阻塞与非阻塞

【阻塞调用概念】:是指调用结果返回之前,当前线程会被挂起函数只有在得到结果之后才会返回。
【举例】:依然是你给隔壁老王打电话,要他家Wifi密码,老王说他要找一下。这时你没有挂电话,而是把自己这个线程给挂起了(即该线程被置于睡眠(Sleep)状态),为的是先不去切菜而是默默等老王给你密码,等他告诉你密码后(线程被唤醒),你再去切菜。此处的阻塞调用指的是你被挂起、被置于睡眠的这种状态

【非阻塞调用概念】:是指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。
【举例】依然是上面的案例,你给隔壁老王打电话,要他家Wifi密码,老王说他要找一下。这时你说让他慢慢找,等找到后在给你打电话告知,于是你便变挂了电话去执行下一个切菜任务。此处的非阻塞调用指的是你在处理这些任务时,不需要被挂起,而可以去执行其他任务的状态。

【总结】

特点区别
同步主动等待强调消息通信机制
异步被动等待强调消息通信机制
阻塞被挂起强调程序等待结果的状态
非阻塞不会被挂起强调程序等待结果的状态

【参考文献】:
[1] Dale工作学习笔记.
[2] 百度百科-非阻塞系统.

本文标签: 形象