有没有办法让stdin读取超时,以免程序挂起太长时间?
read(0, var, numberofbytes);
答案 0 :(得分:11)
您可以使用ncurses,或者如果您不想,可以按照此blog post中的说明使用select。基本上,您可以使用select
并指定超时。如果设置了stdin FD,那么您可以安全地读取它并且不会阻塞。如果您想了解有关选择的更多信息,请选择this,当然还有wikipedia。知道这是一个方便的电话。
编辑:我觉得有必要提供代码,所以在这里,直接来自博客文章并附上一些评论。
// if != 0, then there is data to be read on stdin
int kbhit()
{
// timeout structure passed into select
struct timeval tv;
// fd_set passed into select
fd_set fds;
// Set up the timeout. here we can wait for 1 second
tv.tv_sec = 1;
tv.tv_usec = 0;
// Zero out the fd_set - make sure it's pristine
FD_ZERO(&fds);
// Set the FD that we want to read
FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0
// select takes the last file descriptor value + 1 in the fdset to check,
// the fdset for reads, writes, and errors. We are only passing in reads.
// the last parameter is the timeout. select will return if an FD is ready or
// the timeout has occurred
select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
// return 0 if STDIN is not ready to be read.
return FD_ISSET(STDIN_FILENO, &fds);
}
答案 1 :(得分:6)
使用select,poll或任何其他IO多路复用工具。他们都采取超时论证。 请注意,如果stdin是常规文件,这将不起作用,但如果stdin是终端/ tty,套接字,管道,它将会起作用。
e.g。
fd_set selectset;
struct timeval timeout = {10,0}; //timeout of 10 secs.
int ret;
FD_ZERO(&selectset);
FD_SET(0,&selectset);
ret = select(1,&selectset,NULL,NULL,&timeout);
if(ret == 0)
//timeout
else if(ret == -1)
//error
else
// stdin has data, read it
// (we know stdin is readable, since we only asked for read events
//and stdin is the only fd in our select set.
答案 2 :(得分:0)
在致电alarm()
之前致电ualarm()
或read()
。这将导致SIGALRM
信号传递给进程,中断read(),提供的,您没有告诉O / S在中断后重新启动系统调用。如果read()
正常返回,请务必取消闹钟。