1

有没有办法让两个函数共享一个变量而不使其成为全局变量并且不能传递它?或者有没有办法在使用时将变量传递给函数signal()

具体来说,我有一个 main() 打开文件并对其进行处理并保持打开一段时间。有一个小函数在fd处理完文件后接受(和其他一些信息)main() 调用。

我现在正试图通过捕捉致命信号并在需要时处理事情来使事情变得更加强大。尽管我无法弄清楚如何在不使fd所有其他需要的变量全局化的情况下做到这一点。我宁愿避免的事情。

(void)signal(SIGINT, die);

static void die(int sig)
{
    endTrip(fd, &tripID); //Quickly writes a footer and fcloses
    exit(sig);
}

有没有比让一切都全球化更好的解决方案?

编辑

这样的事情可能吗

static void die(int sig, FILE *fd)
{
    const FILE *local_fd;
    if(sig == NULL)
        {local_fd = fd;}
    else
    {
        endTrip(local_fd, &tripID); //Quickly writes a footer and fcloses 
        exit(sig);
    }
}


main() {
  ...
  // When i open new file let die know.
  die(NULL, fd);
  ...
}
4

4 回答 4

2

信号处理程序已经是全局状态。如果您使用的是一个,那么您已经过了不归路,并且您已经在使用一个全局变量,尽管它通常隐藏在内核空间中(信号处理程序指针)。此时,为参数添加另一个全局变量并完成它并没有什么大不了的。

话虽如此,您可能应该考虑您的整个设计是否有效。从信号处理程序中使用 stdio 是无效的,除非在很难保证的非常特殊的情况下。在您的情况下,由于被信号处理程序中断的代码似乎在同FILE一流上运行,因此从信号处理程序中触摸它几乎肯定是无效的。

此外,您可能会考虑如果您的程序是或曾经适应多线程会发生什么。整个过程只有一组信号处理程序,但多个文件可能正在不同的线程中写入。

有很多不同的方法可以解决这样的问题,但最简单和最便携的方法是打开一个管道返回给自己,让信号处理程序只向管道写入一个字节。然后,您的主循环代码可以检测管道读取端的输入(例如,使用selector poll)并在信号处理程序上下文之外,在它自己的上下文中对其进行操作,在该上下文中它可以访问自己的局部变量等。

于 2012-08-22T05:19:26.830 回答
0
static void die(int sig, FILE *fd) { 
    static const FILE *local_fd;
    if(sig == NULL) {
        local_fd = fd;
    }
    ...

我假设您想在下一次函数调用中继续使用 local_fd,这就是为什么您必须将其声明为static const FILE *

于 2012-08-22T05:24:55.117 回答
0

我没有看到另一种使所有变量全局化的解决方案,让事情变得更干净,也许你可以创建一个包含所有变量的结构。

于 2012-08-22T05:06:32.810 回答
0

在单个文件中的两个或多个函数之间共享变量的常规方法(不使其成为全局以便在其他文件中可见)是将其变为static变量。请注意,“fd”通常用作“文件描述符”的缩写(即一个int);您通常使用缩写“fp”来表示 a FILE *

static FILE *local_fp;
static void die(int signum);

int main(void)
{
    local_fp = fopen("...");
    signal(SIGINT, die);
    ...
    ...use local_fp...
    fclose(local_fp);
    local_fp = 0;
    ...
    return(EXIT_SUCCESS);
}

static void die(int signum)
{
    if (local_fp != 0)
        fclose(local_fp);
    exit(EXIT_FAILURE);
}

这显示了两个函数,它们都能够访问变量local_fp。缺少在两个函数之间传递值或指针作为参数,或者使用共享内存的各种技巧最终使用变量(全局、静态或作为参数传递给函数)来访问共享内存,没有办法一对共享对变量的访问的函数。

我不太确定你的功能是什么,我也不太确定信号如何融入混合物中。

请注意,您应该int main(void)明确说明返回类型。C99 不允许您省略返回类型(C11 也不允许)。

于 2012-08-22T05:15:58.110 回答