有没有办法让两个函数共享变量而不使其成为全局变量并且无法传递它?或者有没有办法在使用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);
...
}
答案 0 :(得分:2)
信号处理程序已经处于全局状态。如果你正在使用一个,那么你已经传递了无法返回的点并且你已经使用了一个全局变量,尽管它通常隐藏在内核空间(信号处理程序指针)中。在这一点上,为参数添加另一个全局变量并完成它并没有什么大不了的。
话虽如此,您应该考虑整个设计是否有效。使用信号处理程序中的stdio 无效除非在非常特殊的情况下难以保证。在您的情况下,由于被信号处理程序中断的代码似乎在相同的FILE
流上运行,因此从信号处理程序触摸它几乎肯定无效。
此外,您可能会考虑如果您的程序是多线程的,或者曾经适应多线程会发生什么。整个过程只有一组信号处理程序,但可能会在不同的线程中写入多个文件。
你可以采取许多不同的方法来解决这样的问题,但最简单和最便携的方法是打开一个管道给自己,让信号处理程序什么也不做,只是写一个字节到管道。然后,您的主循环代码可以检测管道读取端的输入(例如,使用select
或poll
)并在信号处理程序上下文之外对其进行操作,在其自己的上下文中访问自己的局部变量等。
答案 1 :(得分:0)
我没有看到另一个解决方案,使所有变量全局化,使事情更清晰,也许你可以创建一个包含所有变量的结构。
答案 2 :(得分:0)
在单个文件中共享两个或多个函数之间的变量的常规方法(不将其设置为全局以便在其他文件中可见)是将其变为static
变量。请注意,'fd'通常用作'文件描述符'的缩写(它是int
);通常使用缩写“fp”表示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也不允许)。
答案 3 :(得分:0)
static void die(int sig, FILE *fd) {
static const FILE *local_fd;
if(sig == NULL) {
local_fd = fd;
}
...
我假设你想在下一个函数调用时继续使用local_fd,这就是你必须将它声明为 static const FILE * 的原因。