使用 fgets 作为非阻塞函数 c++

发布于 2024-11-08 05:46:44 字数 205 浏览 0 评论 0原文

我正在编写一个程序,使用函数 fgets 从 stdin 循环读取,如下所示:

while(fgets(buffer2, BUFFERSIZE , stdin) != NULL){
  //Some code  
}

我希望我的代码是非阻塞的,即:我不希望程序保留“fgets”当用户当前没有输入时,该行。
我该怎么做?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

自此以后,行同陌路 2024-11-15 05:46:44

fgets() 是一个阻塞函数,它意味着等待数据可用。

如果要执行异步 I/O,可以使用 select()poll()epoll()。然后当有数据可用时从文件描述符执行读取。

这些函数使用 FILE* 句柄的文件描述符,通过以下方式检索:

int fd = fileno(f);

如果您使用的是 Unix 或 Linux,则一种解决方案是将文件使用的文件描述符标记为非阻塞。示例:

#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 现在应该是非阻塞的,并将返回 null 并为您设置错误代码。

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.

沫离伤花 2024-11-15 05:46:44

如果您有适当的 POSIX 环境,则可以在调用之前使用 select()poll() 检查 stdin 描述符上的输入fgets()...read()

下面 Jan 的评论(谢谢!)解释了为什么您不能通过这种方法使用 fgets()...总之,FILE 对象中有一个额外的缓冲层,尽管 select() 在文件描述符上找不到更多内容,但数据可能已经在等待...阻止您的程序及时响应,并且如果其他系统正在等待某个数据,则可能会挂起在 stdin 上发送更多数据之前响应已发送的数据。

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.

眼泪也成诗 2024-11-15 05:46:44

您基本上有两个选择:

  1. 在单独的线程中运行该循环。
  2. 检查您的操作系统是否支持某些非阻塞 IO 的 API。

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.
骄傲 2024-11-15 05:46:44

这听起来有点矫枉过正,但这就是我想到的。

使用两个不同的线程 - 一个使用这个循环并等待阻塞(我不认为这可以非阻塞地完成)。当读取到某些内容时,将其推入管道中。

与此同时,另一个线程将做任何它需要做的事情,并时不时地检查管道中的数据(显然,你希望这是异步的,或者至少我是这样得到的。如果是这样,这意味着不同的线程)

但是,您需要很好地同步两个线程。您应该检查操作系统的多线程和 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.

葵雨 2024-11-15 05:46:44

在 Linux 上,您可以通过按 ctrl-d 来指定输入结束,当然您可以使用单独的线程来执行此操作。

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文