事件驱动和异步通常用作同义词。这两者之间有什么不同吗?
另外,epoll
和aio
之间有什么区别?它们如何结合在一起?
最后,我多次读过Linux中的AIO被严重破坏。究竟是怎么破坏的?
感谢。
答案 0 :(得分:22)
事件是实现异步执行的范例之一。 但并非所有异步系统都使用事件。这是关于这两者的语义 - 一个是另一个的超实体。
epoll和aio使用不同的比喻: epoll是一个阻塞操作(epoll_wait()
) - 你阻塞线程直到某个事件发生,然后你将事件分派给代码中的不同过程/函数/分支。
在AIO中,您将回调函数(完成例程)的地址传递给系统,系统在发生事件时调用您的函数。
AIO的问题是你的回调函数代码是从系统线程运行的,所以在系统堆栈之上。你可以想象的一些问题。
答案 1 :(得分:19)
它们完全不同。
事件驱动的范例意味着只要有事情发生,就会向程序发送一个称为“事件”的对象,而不必定期轮询“某事”以发现它是否已经发生。该“事件”可能被程序捕获以执行某些操作(即“处理程序”) - 同步或异步。
因此,事件的处理可以是同步的也可以是异步的。例如,JavaScript使用同步事件系统。
异步意味着操作可以独立于当前的“主”执行流而发生。请注意, NOT 表示“并行”或“不同线程”。 “异步”动作实际上可以在主线程上运行,同时阻止“主”执行流。所以不要混淆“异步”和“多线程”。
从技术上讲,您可以说,异步操作会自动假定事件 - 至少“已完成”,“出现故障”或“已中止/已取消”事件(其中一个或多个)是发送给操作的发起者(或基础操作系统本身)以发出操作已停止的信号。因此,异步始终是事件驱动的,但不是相反的。
答案 2 :(得分:2)
事件驱动是一个单线程,其中为特定场景注册事件。当面临这种情况时,会触发事件。然而,即使在那时,每个事件都以顺序方式触发。关于它没有任何异步。 Node.js(webserver)使用事件来处理多个请求。
异步基本上是多任务处理。它可以产生多个线程或进程来执行某个功能。它与事件驱动完全不同,因为每个线程都是独立的,并且很难以简单的响应方式与主线程交互。 Apache(webserver)使用多个线程来处理传入的请求。
答案 3 :(得分:2)
最后,我读过很多遍Linux上的AIO被严重破坏了。到底是怎么破的?
AIO as done via KAIO/libaio
/io_submit
comes with a lot of caveats,如果您希望它表现得好而不是无声阻止,则很难很好地使用(例如,仅在某些类型的fd上有效,而在使用文件/阻止设备时才真正起作用直接I / O,但这只是冰山一角。最终它确实获得了indicate file descriptor readiness with the 4.19 kernel)的功能,这对于使用套接字的程序很有用。
POSIX AIO on Linux is actually a userspace threads implementation by glibc并有其自身的局限性(例如,它被认为是缓慢的并且扩展性不好)。
最近(2020年),io_uring
希望在Linux上以更少的痛苦和折衷进行任意异步I / O ...