我正在浏览一个串行程序,我观察到他们在使用read()
之前使用了select()
read()
。 为什么这是必需的。 为什么不能直接调用read()
并检查是否失败? 还有,为什么我们必须递增文件描述符1,并传递它,而我已经传递文件描述符已设置为select()
?
例:
r=select(fd+1, &fds, NULL, NULL, &timeout);
其中fds已经具有fd的值
select()
系统调用将告诉您是否有任何数据要读取您感兴趣的文件描述符。严格来说,这是文件描述符上的读操作是否会被阻塞的问题。
如果在文件描述符(如连接到串口的文件描述符read()
上执行read()
,并且没有要读取的数据,则调用将挂起,直到有一些数据要读取。 使用select()
程序不希望像那样被阻塞。
你也问:
为什么我们必须递增文件描述符1并传递它,而我传递的文件描述符集已经
select
?
这可能是指定FD_SET的大小, 但可能做得不好 。 select()
的第一个参数被称为nfds
,POSIX说:
nfds
参数指定要测试的描述符的范围。 首先在每组中检查nfds
描述符; 即描述符集中从零到nfds-1
的描述符应被检查。
所以,为了测试文件描述符n
, nfds
的值必须至少为n+1
。
想要在阅读交互式用户输入1时继续运行的程序需要是多线程的, 或者需要仔细阅读输入流,特别是有条件地阅读输入流。
Select(2)
可以用来实现第二种设计模式。 它可以确定是否可以读取输入而不会阻塞整个应用程序。
或者其他一些不可预测的输入。
当你必须不断地监视文件描述符,直到它们准备好一些没有阻塞的IO时,你可以使用select调用。
当你想要IO(例如read())非阻塞时通常使用,请阅读: 手册页
也读相关的API