2

“重写 'fgets' 以包含警报,这样如果 5 秒后用户没有输入任何数据,'fgets' 将返回指向 NULL 的指针(超时)”

这是一项大型家庭作业的问题,我们才刚刚开始研究信号、捕捉、处理等。话虽如此,这本书和讲座幻灯片都缺乏这方面的内容......

我想到了创建一个处理程序来捕获这种类型的异常,并且我了解警报的工作原理,但我不了解接口将如何工作。

现在只想着“fgets”......如果我只是在所有其他工作完成之前(就在我的返回指针之前)放一个警报:

char *fgets(//...//)
{
    alarm(5);
    char * to_return = NULL;
    //...//

如果警报在用户输入数据之前响起,我的处理程序可以“返回 NULL”吗?处理程序完成后,执行是否会在“fgets”中恢复?我想我对处理程序在函数内部可以做什么感到困惑(即它可以强制函数返回一些值,它可以修改函数中声明的变量,它可以强制跳转到不同的函数调用吗? ETC。)

4

1 回答 1

1

首先,信号处理程序是一个单独的执行线程。当信号发出时,您的代码的“正常”执行被中断,信号处理程序被执行,一旦处理程序返回,您的代码的执行将在它被中断的点恢复。

所以,1)你的信号处理程序不能影响你的返回fgets()(至少不是直接的),2)它不能返回一个值。(您可能会注意到,signal()安装信号处理程序的函数需要一个指向以整数作为参数并具有void返回类型的函数的指针。

信号处理程序可以做的是设置一个值。标准(C99,“信号处理”一章,7.14.1.1 (5))对此表示:

如果信号不是由于调用abortorraise函数而发生的,则如果信号处理程序引用具有静态存储持续时间的任何对象,而不是通过将值分配给声明为的对象volatile sig_atomic_t,或者信号处理程序调用任何函数,则行为未定义在标准库以外的abort 函数、_Exit函数或signal函数中,第一个参数等于导致调用处理程序的信号对应的信号编号。

这意味着,您可以声明一个类型的变量,volatile sig_atomic_tfgets()和您的信号处理程序都可以“看到”它,将其初始化为默认值,并让信号处理程序更改该值,以便您fgets()可以看到信号已触发。

当然,如果您fgets()等到用户输入某些内容,即使在信号触发后它也会等待......如何解决这个问题取决于您如何进行输入。getch()要么对输入(不是 ISO/ANSI C)使用非阻塞检查,要么依赖read()提到的 R. 的行为(依赖于下面的 POSIX 层fgets()),或者其他东西。我想不出严格的 ISO/ANSI C 方法来做到这一点,所以这取决于你在课程中已经学到/做了什么。

哦,如果您觉得勇敢,请告诉您的教练,将标准函数重新定义为不同的行为是一个非常糟糕的主意(避免称他为“愚蠢”)。如果你想要一个fgets()不是真的fgets(),给它一个不同的名字,例如fgets_timed()

于 2012-06-06T07:46:50.750 回答