I'm writing a program that reads in a loop from the stdin, using the function fgets, as follows:
while(fgets(buffer2, BUFFERSIZE , stdin) != NULL){
//Some code
}
I want my code to be non-blocking, that is: I don't want the program to hold on the 'fgets' line when there's no input at the moment from the user.
How can i do it?
fgets()
is a blocking function, it is meant to wait until data is available.If you want to perform asynchronous I/O, you can use
select()
,poll()
, orepoll()
. And then perform a read from the file descriptor when there is data available.These functions use the file descriptor of the FILE* handle, retrieved by:
If you are using Unix or Linux, then one solution can be to mark the file descriptor used by the file to be non-blocking. Example:
fgets
should be non-blockng now and will return a null and set an error code for you.On Linux, you can specify the end of input by pressing ctrl-d, and of-course you can do this using separate thread.
If you have a proper POSIX environment, you can use
select()
orpoll()
to check for input onstdin
's descriptor before calling...fgets()
read()
.Jan's comment below (thanks!) explains why you can't use
fgets()
with this approach... summarily, there's an extra layer of buffering in theFILE
object, and data can already be waiting in though theselect()
finds nothing more on the file descriptor... preventing your program from responding in a timely way, and potentially hanging if some other system is waiting for a response to already sent data before sending more onstdin
.You basically have two options:
This would sound a little like overkill, but this is the one, that comes to my mind.
Use 2 different threads - one using this loop and waiting blocking ( I don't think that this could be done non-blocking). And when something is read, push it into a pipe.
Meanwhile, the other thread will do whatever it needs to do and check for data in the pipe from time to time ( apparently, you want this to be asynchronous, or at least I get it this way. If so, this means different threads )
But then, you'll need to synchronize the two threads very well. You should check your OS about multithreading and IO operations.