开发者

using fgets as non-blocking function c++

开发者 https://www.devze.com 2023-03-07 10:57 出处:网络
I\'m writing a program that reads in a loop 开发者_如何学Gofrom the stdin, using the function fgets, as follows:

I'm writing a program that reads in a loop 开发者_如何学Gofrom 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(), or epoll(). 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:

int fd = fileno(f);

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:

#include <fcntl.h>  
FILE *handle = popen("tail -f /als/als_test.txt", "r"); 
int fd = fileno(handle);  
flags = fcntl(fd, F_GETFL, 0); 
flags |= O_NONBLOCK; 
fcntl(fd, F_SETFL, flags); 

fgets should be non-blockng now and will return a null and set an error code for you.


If you have a proper POSIX environment, you can use select() or poll() to check for input on stdin'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 the FILE object, and data can already be waiting in though the select() 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 on stdin.


You basically have two options:

  1. Run that loop in a separate thread.
  2. Check if your OS supports some API for non-blocking IO.


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.


On Linux, you can specify the end of input by pressing ctrl-d, and of-course you can do this using separate thread.

0

精彩评论

暂无评论...
验证码 换一张
取 消