同步异步与阻塞非阻塞

很多人一开始盲目的认为同步就是阻塞,异步就是非阻塞。其实这是错误的,首先我们先要区分开同步并非阻塞,异步并非非阻塞。

同步和异步关注的是消息通信机制。

同步

所谓同步就是,当发出一个“调用”地时候,在没有得到结果前,该调用就不会返回,但是一旦返回,就会有返回值。也就是说必须一件一件的做事情,直到当前事件处理完成,才能做下一件事。

异步

而异步的概念与同步刚好相反,即当发出一个“调用”后,调用者不能立即得到结果,即该调用没有返回值。实际上在处理这个调用的部件(被调用方),会通过状态、通知来通知调用方或者使用回调函数。

阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.

阻塞

阻塞调用是指调用结果返回之前,当前进程将会被挂起(线程则会进入非可执行状态,在这个状态下,cpu不会给线程分配时间片,即线程暂停运行)。函数只有在得到结果之后才会返回。

有人也许会把阻塞调用和同步调用等同起来,实际上他是不同的。对于同步调用来说,很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回,它还会抢占cpu去执行其他逻辑,也会主动检测I/O是否准备好。

非阻塞

非阻塞调用是指在不能立刻得到结果前,该函数不会阻塞当前进程,而是立刻返回。

Linux下的五种I/O模型

  • 阻塞I/O(blocking I/O)
  • 非阻塞I/O (nonblocking I/O)
  •  I/O复用(select 和poll) (I/O multiplexing)
  • 信号驱动I/O (signal driven I/O (SIGIO))
  • 异步I/O (asynchronous I/O (the POSIX aio_functions))

其中前4种都是同步,最后一种才是异步。

阻塞I/O模型:

在调用recv()/recvfrom()函数时,发生在内核中等待数据和复制数据的过程。

当调用recv()函数时,系统首先查是否有准备好的数据。如果数据没有准备好,那么系统就处于等待状态。当数据准备好后,将数据从系统缓冲区复制到用户空间,然后该函数返回。在套接应用程序中,当调用recv()函数时,未必用户空间就已经存在数据,那么此时recv()函数就会处于等待状态。

非阻塞I/O模型

非阻塞式I/O在应用进程发出recv请求时,如果内核数据并没有准备好,那么会直接返回一个error,说明数据未就绪,此时应用进程也不必死等在这里了,可以去做别的事情,但是需要定时的询问内核数据是否就绪。特点就是数据未就绪时不阻塞,但轮询的询问内核数据是否就绪。

I/O复用模型

 对一个IO端口,两次调用,两次返回,比阻塞IO并没有什么优越性;关键是能实现同时对多个IO端口进行监听; I/O复用模型会用到select、poll、epoll函数,这几个函数也会使进程阻塞,但是和阻塞I/O所不同的的,这两个函数可以同时阻塞多个I/O操作。而且可以同时对多个读操作,多个写操作的I/O函数进行检测,直到有数据可读或可写时,才真正调用I/O操作函数。

信号驱动I/O模型

首先我们允许套接口进行信号驱动I/O,并安装一个信号处理函数,进程继续运行并不阻塞。当数据准备好时,进程会收到一个SIGIO信号,可以在信号处理函数中调用I/O操作函数处理数据。

异步I/O模型

当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者的输入输出操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值