40

我正在通过一个串行程序,我观察到他们select()在使用read(). 为什么需要这样做。为什么我们不能直接调用read()并检查它是否失败?另外,为什么我们必须将文件描述符增加 1 并在我将文件描述符集传递给时传递它select()

例子:

r=select(fd+1, &fds, NULL, NULL, &timeout); 其中 fds 已经具有 fd 的值

4

3 回答 3

45

系统select()调用告诉您是否有任何数据要读取您感兴趣的文件描述符。严格来说,这是一个文件描述符上的读取操作是否会阻塞的问题。

如果您read()在文件描述符上执行——例如连接到串行端口的文件描述符——并且没有要读取的数据,那么调用将挂起,直到有一些数据要读取。使用的程序select()不希望这样被阻止。

你还问:

为什么我们必须将文件描述符增加 1 并在我将文件描述符集传递给时传递它select

这可能是指定 FD_SET 的大小。的第一个参数select()被称为nfds和 POSIX 说:

nfds参数指定要测试的描述符范围。nfds应在每组中检查第一个描述符;nfds-1也就是说,应检查描述符集中从零开始的描述符。

因此,要测试文件描述符n, in 的值nfds必须至少为n+1.

于 2013-01-27T05:13:26.253 回答
8

想要在读取交互式用户输入1的同时继续运行的程序需要是多线程的,或者他们需要仔细读取输入流,特别是有条件的读取。

Select(2)可用于实现第二种设计模式。它可以确定是否可以在不阻塞整个应用程序的情况下读取输入。


1. 或其他不可预测的输入。

于 2013-01-27T05:28:13.787 回答
3

当您必须不断监视文件描述符直到它们准备好进行某些 IO 而不阻塞时,您可以使用 select 调用。

通常在您希望 IO(例如 read() )非阻塞时使用,请阅读:手册页

另请阅读相关 API

于 2013-01-27T05:13:55.010 回答