目前我对select(2)有点困惑,摘要中指出:
据我所知,select,pselect,FD_CLR,FD_ISSET,FD_SET,FD_ZERO-同步I / O 多路传输
许多库和程序(例如libuv和nodejs)将select / epoll / kqueue / iocp用于其事件循环,该循环用于其相应的async / await功能(和async I / O?)。
那么,同步复用到底是什么意思?我可以使用select实现异步I / O吗? 同步多路复用和异步多路复用之间到底有什么区别?
答案 0 :(得分:4)
那里有一个解析错误。它不是同步复用,而是同步I / O的复用:select
用于复用同步I / O调用。 read
和write
等被称为同步I / O,因为它们要么阻塞直到传输完成,要么不进行传输(例如,非阻塞非就绪套接字)。
这可以与真正的异步调用形成对比,在真正的异步调用中,系统调用仅启动传输,并在后台完成,并在完成后发出通知。
nodejs和libuv是不同的野兽。即使C中的I / O可能是多路复用的,也可能是同步的,但对于它们来说,它似乎是异步的-没有阻塞的同步读取调用,因为它们都在C /库侧透明地发生。 >
答案 1 :(得分:1)
那么,同步多路复用到底是什么意思?
同步操作与异步操作的区别在于,前者不允许调用者继续执行直到完成,而后者则允许。 软件(a)同步性与多线程紧密相关,select()
的主要特征是,它可以完全在单个(用户)执行线程中工作,这使它的操作同步而不是异步。 。当您调用select()
时,线程将阻塞,直到您指定的文件描述符之一准备就绪或指定的超时时间到期为止。
替代方法是编程模型,在该模型中,您在文件描述符上注册对I / O的兴趣,然后稍后再回来检查它们是否准备就绪。
但是,应注意,尽管select()
本身肯定是同步的,但多路复用主要取决于程序员。 select()
提供了实现此目标的方法,但本身不执行I / O。至关重要的是为您提供所需的信息,以避免在准备好为另一个文件描述符提供服务的同时阻止尝试对一个文件描述符执行I / O。
我可以使用select实现异步I / O吗?
否,select
并没有采取任何措施来特别促进异步I / O。它可以帮助您通过单个线程有效地处理多个I / O通道,但是该线程是同步运行的。但是,这往往是一个大的胜利,因为I / O非常慢,而这种缓慢主要与I / O外设和介质有关,而不与CPU和内存有关。一般来说,只要一个线程明智地选择在任何给定的机会处理哪个I / O通道,它就具有足够的处理能力来处理多个I / O通道,而select()
可以简化这一工作。