I have a fd descriptor, which I can use to read from by calling read(fd, buffer,...)
. Now, I want to check if there is a开发者_StackOverflow社区nything to read before actually making the call, because the call is blocking. How do I do this?
int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
The code snippet above will configure such a descriptor for non-blocking access. If data is not available when you call read, then the system call will fail with a return value of -1 and errno is set to EAGAIN. See the fnctl man pages for more information.
Alternatively, you can use select with a configurable timeout to check and/or wait a specified time interval for more data. This method is probably what you want and can be much more efficient.
Use select
or poll
to query whether the file descriptor has data available for read:
fd_set fds;
FD_ZERO(&fds);
FD_SET(&fds, fd);
if (select(fd+1, &fds, 0, 0)==1) /* there is data available */
Depending on what you're doing you might be able to turn the problem inside out and use select
to tell you when your file descriptor has something to read.
use poll for timeout:
struct pollfd p;
int n;
while ((n = poll(&p, 1, iTo)) < 0)
{
if (errno == EAGAIN || errno == EINTR)
continue;
}
if (!n) {
errno = ETIMEDOUT;
}
while ((len = read(Fd, anyBuff, sizeof(anyenter code hereBuff))) < 0) {
if (errno == EAGAIN || errno == EINTR)
continue;
}
I think you should use select
or poll
functions to check if there are something to read from the descriptor.
Check out the API or system/tool you are using for your specific programming purpose. (descriptors/file descriptors have many uses in Linux programming such as socket programming, file manipulation, shared_memory, etc.)
For example one time I used inotify (for monitoring file system events). This API gives you ability to create non-blocking file from the first point and there's no need to use fcntl or such APIs to modify the created file descriptor.
Probably other tools or API's that you're going to use have such functionality and you can set such option in their initiation or such steps (check this first).
But generally yes using fcntl is the answer and it might be interesting to know that inotify itself uses fcntl itself too. (refer to the manual pages of Linux)
select() can give you a same functionality as it operates on file descriptors for monitoring events with a specified limited time but keep in mind that the main usage of select is for monitoring multiple file descriptors.
精彩评论