JavaScript 进阶营前端开发笔记

阻塞&非阻塞和同步&非同步

2019-02-17  本文已影响20人  隔壁老王的隔壁啊

一、阻塞&非阻塞

1、阻塞IO

调用之后一定要等到系统内核完成所有的操作之后才结束,因此它的缺点:CPU等待IO,处理能力得不到充分利用。

2、非阻塞IO

为了解决阻塞IO带来的一些问题,内核提供了非阻塞IO,非阻塞IO的差别是调用之后会立即返回。缺点:非阻塞IO立即返回并不是业务层期望的数据,而仅仅是调用的状态,为了获取完整的数据,应用程序需要重复调用IO操作确认,即轮询。

3、轮询

常见的三种轮询方式:select、poll和epoll。

1、select

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

参数解释

通过设置或者检查存放fd(文件标识符)标志位的数据结构进行处理(select对应于内核的sys_select调用):1.将第2、3、4个参数指向的fd_set拷贝到内核;2.对每个被set对描述符调用进行poll,并记录在临时结果中(fdset)
缺点是:

2、poll

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

poll和select的实现机制类似,对应内核的sys_poll,但是传递的是pollfd数组,接着对pollfd数组进行poll。
优点:

3、epoll

int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

相对于select和poll的遍历查询,epoll是真实利用了执行回调和事件通知的机制,充分利用CPU,因此效率比较高。

4、总结
总的来说,轮询技术满足非阻塞IO确保完整数据获取的需求,当时对于应用程序来说,它仍然是同步,因为它必须等待IO完全返回。等待IO期间,CPU要么遍历文件描述符的状态,要没用于休眠等待事件发生。

二、同步&异步

1、同步IO

同步IO比较简单,就是简单的顺序执行,其实阻塞和非阻塞都属于同步IO。

2、异步IO

这里拿Node举例,在Node中,我们知道异步是它的一大特色,那它到底有哪些好处呢?
好处

远离

我们期待的异步是:当我们应用程序发起阻塞请求,不需要轮询技术,直接处理下一个任务;当阻塞请求完成之后,将数据传递到应用程序。在Linux下存在这种异步IO即AIO。
如果我们自己去实现异步IO,则可以通过线程池+轮询技术来实现数据的获取。例如现在应用程序发起了一个阻塞请求,我们可以如下处理:

  1. 让a线程利用轮询技术去处理阻塞调用
  2. 让b线程去执行计算处理
  3. 当a线程的处理结果通过线程间共享发送给b
    这样,就完成了异步IO。

三、总结

通过上面的介绍,我们需要知道的是:阻塞&非阻塞和异步&同步是不能混为一谈的,非阻塞本质上还是同步,它所谓的返回只是状态并不是数据

由于阻塞&非阻塞和异步&同步的概念十分类似,这里就其做了一个简单介绍

欢迎关注公众号

码农求道
上一篇下一篇

猜你喜欢

热点阅读