同步异步以及并行和并发

同步IO/异步IO的区别

对于这个问题,每个人的理解不一样,但殊途同归。拿IO操作的Read和Write举例,Read执行的情况下,对于默认的socket都是阻塞的,因此Read这个函数得不到返回值,并且一直阻塞在那里,整个线程不能进行其他操作,至于阻塞构成的原因是由于Read需要等待socket连接的另一方将数据发送过来,并且通过系统调用陷入内核,拷贝数据,并将数据返回到用户态。一旦这两个条件结束,Read的阻塞被解除。当然也有可能这两个条件永远不来,那么Read函数可能会收到超时返回值,根据超时时间而定。Write函数同理,两部操作分别是等待数据输入,拷贝到内核缓冲区。

异步IO的话,往往不会伴随着阻塞行为。先说异步的函数以及非阻塞IO,以recv和send举例,如果scoket被设置成非阻塞,如果数据没有准备好的情况下,那么这两个函数会立即返回一个返回值(error),不会在那里傻傻地等着。然后具体接下来干什么工作,可以根据程序员自己来定,是重新尝试获取这个数据或者是执行其他操作都可以,这样就避免了等待数据这个过程的阻塞。但当数据准备好时,仍然需要拷贝,这一过程仍然是阻塞的。再回到异步IO上,一旦发起recv请求的时候,会立即得到一个返回值,并且接下来就可以去做其他的事了,然后内核等待数据到来,并去把数据拷贝到用户空间之后,发送一个信号,告诉用户数据到你这了,然后切回来去处理这个数据。

对于异步IO和非阻塞IO的区别,有些人认为是一样的,但是这里还是可以看到区别的,特别是在数据拷贝阻塞与否的方面。看上去非阻塞IO的表现是很优秀的,但是频繁的去问内核:“我的货准备好了没有?”,真的好么,注意这里的频繁可能不是我们可以想象的速度。而且操作系统提供了一种技术,保证我们可以去知道“货”准备好了没,又不必在那傻傻地等,这就需要有个检查者帮我们去在那等了,它就是多路IO复用。

epoll的ET和LT

对于多路IO复用,Linux自带的包括select、poll和epoll,所谓后来者居上,epoll最为最新的技术,突破了select和poll的一些缺陷,比如select不能突破1024个fd的限制,poll虽然突破了,但是一次失败的尝试,因为突破1024之后,随着fd的线性增加,响应的效率线性下降,为此epoll诞生。这里需要注意的是,epoll并不是跨平台的,windows下可以使用IOCP,个人认为性能要优于epoll,linux下还有一些第三方性能相对更好的IO模型,比如kqueue。

边缘触发(ET),IO函数只会提醒一次epoll调用者fd上有数据,因此要求调用者必须循环地去把数据都读完,这里可能会造成阻塞,当然可以使用非阻塞IO,甚至是异步IO来提高效率。注意这里如果IO函数提醒你,某个fd上有数据了,你如果不想数据丢掉就必须去读。

水平触发(LT),对于某个fd上有数据的情况下,你可以暂时不去处理,因为LT在你没有处理这个fd上的数据时,下一次的epoll_wait还会提醒你。即使你一次没有读完这个fd上的数据,只读了一部分,下一次还是会提醒你的,你可以再次读,并把数据拼接好,从而继续处理。

对于ET的效率比LT的高,从系统调用次数的角度,确实如此。但是ET要求,对应的fd必须是非阻塞的,并且你要一次性的读取完数据,如果这里可以采用异步IO的话,也还好,但是异步IO对于整个系统的代价也是不小的。在实际使用上,LT的使用更是比ET的要方便,因此我更倾向于LT。

并发和并行

这个是最容易明白,但又是我最容易混淆的两个概念。并发在宏观上看到的是,同时发生,但实际上是以欺骗人眼的速度来切换任务工作的,这也是分时操作系统的最大好处。并行,真正的同时进行,可以是在不同的电脑上或者将任务绑定到固定的cpu核上去执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值