我有一个主循环,我有一个函数,可以显示一个带有一些选择的菜单并等待用户的输入。
关键是我还必须检查是否发生了新事件 - 在我的特定情况下,收到了一条新消息,但这根本不相关 - 我不能等待用户采取行动:我必须实现该功能的超时。
这是我所说的一个简单的例子:
int choice;
for(;;){
/* a new message could be arrived and we should read it now ... */
choice = menu_function();
/*
...but the user still hasn't made an action,
so the menu_function() hasn't returned yet.
*/
switch(choice){
case 1:
break;
case 2:
break;
default:
break;
}
}
到目前为止,我想在menu_function()
之前使用fork()
,并在通过alarm()
接收到SIGALRM
信号后kill()
这个过程,但我认为这不是正确的解决方案,因为它在循环内。
我应该采用什么样的解决方案?
附言我不认为这是重复的,因为正如我已经说过的,中断请求的函数在循环中。或者至少对我来说,我认为这是另一回事。
既然你提到fork
我假设你在POSIX系统上(如Linux或macOS)?
这意味着您可以在执行等待的过程中为SIGALRM
安装一个信号处理程序,并且信号的接收应该中断阻塞操作(使用 errno == EINTR
),您可以检查该操作并让menu_function
返回一个表示"退出"的值。然后,循环中的代码可以检查此值并break
出循环。
另一种选择是不使用标准的 C 输入函数,除非确实有内容要读取。为此,您可以使用具有所需超时的select
调用和轮询FILENO_STDIN
。如果 select
函数返回超时,再次让 menu_function
返回一个表示"exit"的特殊值,否则它将使用标准 C 函数来读取和解析输入。
无需为输入处理程序或计时器分叉新进程。