使用 fgets 作为非阻塞函数 c++
我正在编写一个程序,使用函数 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
fgets()
是一个阻塞函数,它意味着等待数据可用。如果要执行异步 I/O,可以使用
select()
、poll()
或epoll()
。然后当有数据可用时从文件描述符执行读取。这些函数使用 FILE* 句柄的文件描述符,通过以下方式检索:
如果您使用的是 Unix 或 Linux,则一种解决方案是将文件使用的文件描述符标记为非阻塞。示例:
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()
, 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.如果您有适当的 POSIX 环境,则可以在调用之前使用
select()
或poll()
检查stdin
描述符上的输入...fgets()
read()
。下面 Jan 的评论(谢谢!)解释了为什么您不能通过这种方法使用
fgets()
...总之,FILE
对象中有一个额外的缓冲层,尽管select()
在文件描述符上找不到更多内容,但数据可能已经在等待...阻止您的程序及时响应,并且如果其他系统正在等待某个数据,则可能会挂起在stdin
上发送更多数据之前响应已发送的数据。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:
这听起来有点矫枉过正,但这就是我想到的。
使用两个不同的线程 - 一个使用这个循环并等待阻塞(我不认为这可以非阻塞地完成)。当读取到某些内容时,将其推入管道中。
与此同时,另一个线程将做任何它需要做的事情,并时不时地检查管道中的数据(显然,你希望这是异步的,或者至少我是这样得到的。如果是这样,这意味着不同的线程)
但是,您需要很好地同步两个线程。您应该检查操作系统的多线程和 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.
在 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.