同步与异步 阻塞与非阻塞

297 阅读1分钟

阻塞调用: 操作系统或者底层的c库提供的方法或者系统调用在当前条件不满足的情况下, 会让当前的进程在CPU时间片还没有用完的情况下让出CPU的使用权, sleep一段时间。等到条件满足之后再唤醒该进程, 同时返回发起调用的地方。

非阻塞调用: 在条件不满足的情况下, 返回一个告知当前进程。当前进程发现条件不满足可以去处理其他的事情。此时当前进程的CPU时间片没有被剥夺, 仍然可以继续运行下去。

同步和异步: 从编程者边写代码调用的方式而言

同步非阻塞(Python实例):

import asyncio

async def add(a: int, b: int) -> int:
    await asyncio.sleep(1)
    return a + b

async def main():
    nums = [(1, 2), (3, 4), (5, 6)]
    coros = [add(a, b) for (a, b) in nums]
    res = await asyncio.gather(*coros)
    for nums, result in zip(nums, res):
        print(f'{nums[0]} + {nums[1]} =  {result}')

if __name__ == '__main__':
    asyncio.run(main())

结果:

1 + 2 =  3
3 + 4 =  7
5 + 6 =  11

异步非阻塞(Javascript实例):

$(function()  {
    $.ajax({
        "url": "http://httpbin.org/ip",
        "method": "GET",
        "success": function(data) {
            console.log(data)
        }
    });
    console.log("running here before response returns")
});

输出:

running here before response returns
{origin: "xxx.xxx.10.150"}

异步非阻塞的代码一般都是以注册回调函数的形式来处理事件完成后的操作.

而同步非阻塞的代码则是以函数为最小的执行单位, 当当前函数发生阻塞的时候主动切换到其他函数去执行。而不论异步非阻塞还是同步非阻塞的形式, 两者都需要一个EventLoop机制来管理这些还未执行完的任务。