qemu io介绍:同步与异步概念

同步IO的本质
如果使用同步IO的话,那么CPU经常会处于idle状态等待磁盘读写数据完成,因为只有他们完成程序才能继续往下执行。 这时候的CPU资源可以被系统调度,但是用户的应用程序却无法继续往下执行,它必须等待IO完成! 所以同步IO对于应用来说是不好的,因为应用因为串行而阻塞住了,但应用还有很多事情要做,完全可以在这个阻塞的时间内利用到CPU资源。
这段时间如果CPU处于idle状态,那么统计到的是IO wait。 如果有别的应用刚好需要,它是可以在这段时间内利用到CPU资源的,那么统计到的就不是IO wait了。

异步IO的本质
异步IO中io_submit其实也是要到内核中执行,然后等待返回的。 只不过它在内核中不再等待慢速的磁盘,它把数据写到存储的cache就返回了。

同步和阻塞是两个概念。阻塞和非阻塞是关于操作对象来的;而同步异步是关于操作者来着的。
同步要求操作者要去一直管着这个事情;而异步则不管,只是等待被操作者通知时候才会想起这个事情。
阻塞非阻塞是对于被操作者的,有些被操作者你对其操作的时候回阻塞住,有些则不会被其阻塞住。
1. 同步阻塞IO。进程会一直阻塞,得不到调度,在read write返回之前一直无法运行。read write一直阻塞直到有结果。
2. 同步非阻塞。进程会阻塞住,但是内核的read会立刻返回,有可能设备此时还没有数据,直接返回一个EAGAIN。 所以需要进程多次调用读写。(read write下可能是统一的抽象,因为设备自身没有什么阻塞不阻塞的。阻塞与非阻塞模式可能只是设备驱动的两个不同的实现)
3 异步阻塞IO。调用后立刻返回,然后用select来确定下一次可以操作此描述符,然后操作。 有点怪。有两个read或write,也就是两次用户态到内核态的切换,效率有点低。
4. 异步非阻塞。read的时候会立刻返回,当她真正准备好数据后会调用传入的回调或是信号来通知用户态处理。

 

在AIO中,同时会有多个IO请求,所以需要标记不同的请求,也就是aiocb结构。
Linux AIO并非完全的“异步非阻塞”方式。 io_submit在内核中它还是会去阻塞的写,等待写完成。
它必须使用O_DIRECT方式,否则会直接使用O_SYNC方式写。 如果是O_SYNC方式写的话,那异步IO就没有什么意义了。
它有一个优势就是可以同时完成多份IO,因为io_submit的返回值并非是IO是否成功的标志。 而是在epoll出来的eventfd的回调中读取这些IO的结果。

io_submit使用O_DIRECT和 O_SYNC方式时都会阻塞住,只是阻塞的时间长短是不一样。
O_DIRECT会绕开系统的cache直接写入到存储中,但是存储可能有自己的cache,它可能只是写到存储的cache中去了。所以从这个意义上讲也可以说O_DIRECT方式是异步的。
O_SYNC方式的写入会阻塞时间更长,它会保障数据写入到设备中,当它返回后即使直接给设备断电,数据也不会丢失。
如果我们使用O_SYNC的话确实是不需要sync。但是如果qemu层写入的太快,而写入阻塞时间太长的话,那么像线程池方式就会有创建很多的IO线程,也会影响性能。
刚开始我以为io_submit是直接挂链表,然后返回这样的异步;然而他并不是,而是采用O_DIRECT这种异步方式

 如果AIO直接挂链表的话,那么内核必须有一个线程去刷这个链表,系统很难保证这个线程肯定能快速的得到执行,所以不能这样实现。

http://www.ibm.com/developerworks/cn/linux/l-async/
http://www.kuqin.com/linux/20120908/330333.html

posted @ 2017-11-18 14:38  你的KPI完成了吗  阅读(718)  评论(0)    收藏  举报