首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >aio_read内部信号处理程序

aio_read内部信号处理程序
EN

Stack Overflow用户
提问于 2016-03-31 17:02:36
回答 1查看 292关注 0票数 0

当aio完成并触发信号处理程序时,我可能需要执行另一个aio_read调用并继续。

在安全函数中没有提到aio_read (在man信号中)。不过,普通的read才是。

在aio信号处理程序中进行后续aio_read调用的危险是什么?

EN

回答 1

Stack Overflow用户

发布于 2016-04-01 06:29:07

作为可以使用POSIX AIO的proposed Boost.AFIO的作者,我强烈建议不要使用POSIX AIO。我并不是唯一一个持这种观点的人,@arvid同样反对:http://blog.libtorrent.org/2012/10/asynchronous-disk-io/。API本身的设计很差,因此在负载情况下伸缩性很差,除非您使用特定于操作系统的替代方案或AIO的扩展,比如BSD kqueue。POSIX AIO在本质上是无用的。

此外,在您可能正在使用的Linux上,AIO调用不是信号安全的。这是因为在Linux上,它们是使用基于线程池的仿真在用户空间中实现的。在BSD上,AIO调用有一个合适的内核系统调用接口,但在内核中,除非打开了O_DIRECT,否则它会变成-是的,你猜对了-一个基于线程池的仿真。

因此,在POSIX上使用线程池要好得多,除非您所有的i/o都启用了O_DIRECT。如果O_DIRECT确实总是在线的,Linux在http://man7.org/linux/man-pages/man2/io_submit.2.html上提供了一个自定义的内核API,这是相当有效的,并且在BSD上,如果你用BSD kqueue (https://www.freebsd.org/cgi/man.cgi?kqueue,参见EVFILT_AIO)替换信号驱动的处理,那么使用O_DIRECT也可以很好地扩展,无论如何都比线程池更好。

在任何POSIX平台上使用基于信号的完成处理都具有糟糕的性能。AFIO v2提供了一个通用的POSIX后端,它非常可怕,非常可怕。像躲避瘟疫一样躲避。

请注意,线程池同步应用程序接口设计是可移植的,对于大多数用例来说可伸缩性很好,这是我(甚至是arvid)向任何没有高度专业化需求的人推荐的,比如编写数据库后端,其中您需要对物理存储层进行非常严格的控制,而除了O_DIRECT|O_SYNC之外的任何东西都不是一个选择。

好吧,总之,如果你真的想使用信号驱动的aio,我假设这是因为你想多路复用你的文件i/o和非文件i/o的东西,因此你不能使用aio_suspend(),这是做这件事的合适API。AFIO v2处理这个问题的方式是,当需要处理与aio无关的事情时,使用实时信号中断aio_suspend(),然后可以处理它并重新启动aio_suspend()。在处理竞争和死锁时需要非常小心,并且需要仔细地屏蔽和取消屏蔽调用aio_suspend()的线程的信号,以免实时信号丢失,从而丢失唤醒。总而言之,通过线程池+同步API获得的i/o性能通常要低得多,这是不值得的。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36328801

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档