关于I / O复用的一些问题:
select函数将阻塞,直到读取集中的至少一个描述符可以读取为止。当且仅当从该描述符读取1个字节的请求不会阻塞时,描述符k才可以读取。
Q1-我不明白为什么从描述符读取1个字节可能会阻塞?标准IO功能不是使用缓冲区吗?
Q2-为什么不仅仅派生一个子进程,然后让孩子去做可能会阻塞的工作?
Q3-如果我使用无缓冲的系统调用read()从两个打开的文件中读取很多字节,那么它们全部被阻塞(需要很长时间),那么select()如何解复用?
答案 0 :(得分:0)
您误解了select(2)手册页(另请参见select_tut(2))。顺便说一句,您最好在新代码中使用poll(2),例如this;由于select
限制了{{1}的大小)(可以限制C10K problem的使用)(取决于fd_set
的大小)。
select
手册页将file descriptor中的process定义为就绪 ...
也就是说,如果一个文件描述符足以成功read(2)从它开始至少一个字节,则它是一个就绪的文件描述符(用于read
s)。大多数时候,您将能够从中读取多个字节。由于read(2)尝试将被阻止,因此您无法read
无法访问的文件描述符尚未准备就绪,因此可以称为被阻止的文件描述符。
在几种情况下,文件描述符被阻止(即未准备好)。常见的是某个网络socket(7)或某个pipe(7)(或某个终端,请参见pty(7)和the TTY demystified,并请注意line discipline)输入。这就是为什么在Web中需要poll
(或select
,epoll(7)等)来编码event loops(尤其是GUI的widget toolkits)服务器等),因为您要避免忙polling。
有关进一步的解释,请阅读一本不错的Linux编程书,例如ALP 。
您也可以阅读Operating Systems: Three Easy Pieces以获得有关操作系统的更多知识。
请注意,stdio(3)正在实现缓冲 IO(在read(2)和write(2)之上)。另请参见fflush(3)和setvbuf(3)。
另请参见proc(5)以编程方式查询进程的状态(由于在IO操作或事件循环中被阻塞,因此大多数为idle)。或在命令中使用ps(1),top(1)(都在使用/proc/
)。
最后,研究许多free software项目(例如Web服务器,GUI工具包等)的源代码。您可以使用select
或poll
找到许多事件循环的例子。