事件驱动和异步有什么区别? epoll 和 AIO 之间?
事件驱动和异步经常被用作同义词。两者之间有什么区别吗?
另外,epoll
和 aio
之间有什么区别?它们如何组合在一起?
最后,我多次读到 Linux 中的 AIO 严重损坏。具体是怎么坏的呢?
谢谢。
Event-driven and asynchronous are often used as synonyms. Are there any differences between the two?
Also, what is the difference between epoll
and aio
? How do they fit together?
Lastly, I've read many times that AIO in Linux is horribly broken. How exactly is it broken?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
事件是实现异步执行的范例之一。
但并非所有异步系统都使用事件。这就是关于这两者的语义意义——一个是另一个的超实体。
epoll 和 aio 使用不同的比喻:
epoll 是一个阻塞操作 (
epoll_wait()
) - 您阻塞线程,直到发生某个事件,然后将该事件分派到代码中的不同过程/函数/分支。在 AIO 中,您将回调函数(完成例程)的地址传递给系统,系统在发生事件时调用您的函数。
AIO 的问题在于您的回调函数代码在系统线程上运行,因此在系统堆栈顶部运行。正如您可以想象的那样,其中存在一些问题。
Events is one of the paradigms to achieve asynchronous execution.
But not all asynchronous systems use events. That is about semantic meaning of these two - one is super-entity of another.
epoll and aio use different metaphors:
epoll is a blocking operation (
epoll_wait()
) - you block the thread until some event happens and then you dispatch the event to different procedures/functions/branches in your code.In AIO, you pass the address of your callback function (completion routine) to the system and the system calls your function when something happens.
Problem with AIO is that your callback function code runs on the system thread and so on top of the system stack. A few problems with that as you can imagine.
它们是完全不同的东西。
事件驱动范例意味着每当发生某些事情时,就会将称为“事件”的对象发送到程序,而无需定期轮询该“事件”以发现它是否已发生。该“事件”可能被程序捕获以执行某些操作(即“处理程序”)——同步或异步。
因此,事件的处理可以是同步的,也可以是异步的。例如,JavaScript 使用同步事件系统。
异步意味着操作可以独立于当前的“主”执行流而发生。请注意,它并不意味着“并行”或“不同线程”。 “异步”操作实际上可能在主线程上运行,同时阻塞“主”执行流。因此,不要将“异步”与“多线程”混淆。
您可能会说,从技术上讲,异步操作自动假设事件——至少将“已完成”、“故障”或“中止/取消”事件(其中一个或多个)发送到操作的发起者(或底层操作系统本身)发出操作已停止的信号。因此,异步始终是事件驱动的,但反之则不然。
They are completely different things.
The events-driven paradigm means that an object called an "event" is sent to the program whenever something happens, without that "something" having to be polled in regular intervals to discover whether it has happened. That "event" may be trapped by the program to perform some actions (i.e. a "handler") -- either synchronous or asynchronous.
Therefore, handling of events can either be synchronous or asynchronous. JavaScript, for example, uses a synchronous eventing system.
Asynchronous means that actions can happen independent of the current "main" execution stream. Mind you, it does NOT mean "parallel", or "different thread". An "asynchronous" action may actually run on the main thread, blocking the "main" execution stream in the meantime. So don't confuse "asynchronous" with "multi-threading".
You may say that, technically speaking, an asynchronous operation automatically assumes eventing -- at least "completed", "faulted" or "aborted/cancelled" events (one or more of these) are sent to the instigator of the operation (or the underlying O/S itself) to signal that the operation has ceased. Thus, async is always event-driven, but not the other way round.
事件驱动是一个单线程,其中为特定场景注册事件。当遇到这种情况时,事件就会被触发。然而,即使在那时,每个事件也会按顺序触发。没有什么异步的。 Node.js(网络服务器)使用事件来处理多个请求。
异步基本上是多任务处理。它可以产生多个线程或进程来执行某个功能。它与事件驱动完全不同,因为每个线程都是独立的,几乎不以简单的响应方式与主线程交互。 Apache(网络服务器)使用多个线程来处理传入的请求。
Event driven is a single thread where events are registered for a certain scenario. When that scenario is faced, the events are fired. However even at that time each of the events are fired in a sequential manner. There is nothing Asynchronous about it. Node.js (webserver) uses events to deal with multiple requests.
Asynchronous is basically multitasking. It can spawn off multiple threads or processes to execute a certain function. It's totally different from event driven in the sense that each thread is independent and hardly interact with the main thread in an easy responsive manner. Apache (webserver) uses multiple threads to deal with incoming requests.
通过 KAIO/
libaio
/io_submit
完成的 AIO 有很多警告< /a> 如果你希望它表现得更好而不是静默阻塞(例如,仅适用于某些类型的 fd,当使用文件/块设备实际上仅适用于直接 I/O 时,使用起来会很棘手)但这些只是冰山一角)。它最终确实获得了指示 4.19 内核的文件描述符就绪情况的能力,即对于使用套接字的程序很有用。Linux 上的 POSIX AIO 实际上是 glibc 的用户空间线程实现 并且有其自身的局限性(例如,它被认为很慢并且不能很好地扩展)。
如今(2020 年),
io_uring
...AIO as done via KAIO/
libaio
/io_submit
comes with a lot of caveats and is tricky to use well if you want it to behave rather than silently blocking (e.g. only works on certain types of fd, when using files/block devices only actually works for direct I/O but those are the tip of the iceberg). It did eventually gain the ability to indicate file descriptor readiness with the 4.19 kernel) which is useful for programs using sockets.POSIX AIO on Linux is actually a userspace threads implementation by glibc and comes with its own limitations (e.g. it's considered slow and doesn't scale well).
These days (2020) hope for doing arbitrary asynchronous I/O on Linux with less pain and tradeoffs is coming from
io_uring
...