Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-blocking call for reading descriptor

Tags:

c

unix

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 anything to read before actually making the call, because the call is blocking. How do I do this?

like image 694
SmallChess Avatar asked Apr 11 '11 01:04

SmallChess


People also ask

What is a non-blocking file descriptor?

By default, read() waits until at least one byte is available to return to the application; this default is called “blocking” mode. Alternatively, individual file descriptors can be switched to “non-blocking” mode, which means that a read() on a slow file will return immediately, even if no bytes are available.

Is read () a blocking call?

Note: The default mode is blocking. If data is not available to the socket, and the socket is in blocking and synchronous modes, the READ call blocks the caller until data arrives.

What is non-blocking IO in Linux?

For network socket i/o, when it is "ready", it don't block. That's what the O_NONBLOCK and "ready" means. For disk i/o, we have posix aio, linux aio, sendfile and friends. Follow this answer to receive notifications.

What is a difference between a blocking and non-blocking function call?

"Blocking" simply means a function will wait until a certain event happens. "Non blocking" means the function will never wait for something to happen, it will just return straight away, and wait until later to complete the action.


2 Answers

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.

like image 70
Judge Maygarden Avatar answered Sep 30 '22 07:09

Judge Maygarden


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 */ 
like image 43
R.. GitHub STOP HELPING ICE Avatar answered Sep 30 '22 05:09

R.. GitHub STOP HELPING ICE