我正在编写一个程序,使用函数fgets从stdin读取循环,如下所示:
while(fgets(buffer2, BUFFERSIZE , stdin) != NULL){
//Some code
}
我希望我的代码是非阻塞的,即:当用户暂时没有输入时,我不希望程序保留在'fgets'行。
我该怎么办?
答案 0 :(得分:3)
fgets()
是阻止功能,它应该等到数据可用。
如果您要执行异步I / O,可以使用 select()
, poll()
或 {{1} } 即可。然后在有可用数据时从文件描述符执行读取。
这些函数使用FILE *句柄的文件描述符,检索方式为:
epoll()
如果您使用的是Unix或Linux,那么一种解决方案可以是将文件使用的文件描述符标记为非阻塞。示例:
int fd = fileno(f);
#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);
现在应该是非阻止的,并且将返回null并为您设置错误代码。
答案 1 :(得分:2)
如果你有一个合适的POSIX环境,你可以使用select()
或poll()
检查stdin
描述符上的输入,然后再调用 fgets()
罢工> ...... read()
。
Jan的评论如下(谢谢!)解释了为什么你不能使用fgets()
这种方法......总之,FILE
对象中有一层额外的缓冲,数据已经可以了等待虽然select()
在文件描述符上找不到任何其他内容...阻止您的程序及时响应,如果其他系统在发送更多内容之前等待对已发送数据的响应,可能会挂起{1}}。
答案 2 :(得分:1)
您基本上有两个选择:
答案 3 :(得分:0)
这听起来有点像矫枉过正,但这就是我想到的那个。
使用2个不同的线程 - 一个使用此循环并等待阻塞(我不认为这可以完成非阻塞)。当读取某些内容时,将其推入管道。
与此同时,另一个线程会做任何需要做的事情并不时检查管道中的数据(显然,你希望这是异步的,或者至少我这样做。如果是这样,这意味着不同的主题)
但是,你需要很好地同步这两个线程。您应该检查有关多线程和IO操作的操作系统。
答案 4 :(得分:0)
在Linux上,您可以通过按 ctrl-d 指定输入结束,当然您可以使用单独的线程执行此操作。