C-在何处存储在过程内存中的文件描述符



当函数a从执行点调用时,它是对地址指向函数A的JMP语句PC加载称为函数A的地址并继续。

要回到函数调用后的执行点,该功能块应具有相等的推动,并弹出堆栈。通常,在退出功能时,定义的堆栈变量被破坏(我认为这意味着从堆栈中弹出(,但是我决定在函数内定义文件描述符变量。代码如下:

void main() {
    printf("In the beginning there was main()n");
    func_call();
    printf("func_call completen");
    while(1);
}
void func_call() {
    int fp;
    //Opening a file to get handle to it.
    fp = open("stack_flush.c", O_RDONLY);
    if (fp < 0 ) {
        perror("fp could not open stack_flush.c");
        return;
    }
}

在运行此程序并检查LSOF时,我可以看到FD在退出函数func_call((。

时仍在打开。
stack_flu 3791 vvdnlt260    0u   CHR  136,1      0t0        4 /dev/pts/1
stack_flu 3791 vvdnlt260    1u   CHR  136,1      0t0        4 /dev/pts/1
stack_flu 3791 vvdnlt260    2u   CHR  136,1      0t0        4 /dev/pts/1
stack_flu 3791 vvdnlt260    3r   REG    8,3      526 24660187 /home/vvdnlt260/Nishanth/test_space/stack_flush.c

我检查了文件描述符的Wikipedia条目,我发现了以下内容:

要执行输入或输出,该过程通过系统调用将文件描述符传递给内核,并且内核将代表该过程访问文件。该过程无法直接访问文件或inode表。

从上面的语句中很明显,文件描述符整数值存储在过程内存中,但是尽管它是在函数中定义的,但文件描述符并不是该函数的本地,因为它在函数退出时未被删除。

所以我的问题是2倍:

1(如果文件描述符是func_call((堆栈的一部分,则该代码如何返回其前函数调用执行点,尽管尚未弹出?同样在这种情况下,为什么在函数调用后会持续存在?

2(如果不是func_call((堆栈的一部分,则文件描述符位于过程内存中?

变量 int fd;仅从函数 func_call()可见,在执行此功能后,它将被弹出堆栈,并且可能会覆盖内存时输入新功能。您销毁指向文件的一些int值的事实并不意味着您关闭所述文件。如果您做了类似的事情:

int global_fd;
void foo() {
    int local_fd = open("bar.txt", O_RDONLY);
    global_fd = local_fd;
}

并称为foo()?您是否期望无法再使用global_fd Afteer foo退出?

在这种情况下,将文件描述符视为指针,您要求内核给您文件,并且为您提供了一个可以用作此特定文件的令牌的值,此令牌是您用来让内核知道在哪个文件的函数(例如readlseek ACT(的功能。当将令牌传递或破坏时,文件保持打开存储文件描述符的内核中的表。因此,当您打开文件时,您在该表中创建了一个条目。如果您不关闭文件(及其描述符(,则条目永远不会删除(这并不意味着您无法再次打开文件(。

如果文件描述符是func_call((堆栈的一部分,那么尽管尚未弹出,代码如何返回其前功能调用执行点?同样在这种情况下,为什么在函数调用后会持续存在?

据我所知,每个过程只有一个堆栈,而不是每个功能。因此,fp变量存储在该过程的堆栈中,并在功能结束时从那里删除。

文件描述符很特别。如您所知,它们只是Int。但是它们"包含"有关正在读取的文件的大量信息(文件在磁盘上的位置,读/写指针的FIE中的位置等(,那么存储的信息在哪里?答案是它存储在OS内核中。它存储在OS内核中,因为它是为您管理文件I/O的内核工作。当我们说涉及打开文件的int是"文件描述符"时,我们的意思是,int是指存储在其他地方的信息,有点像指针。这个词"描述符"很重要。有时用于这种情况的另一个单词是" hander"。

您知道,局部变量的内存通常存储在堆栈上。当您从函数返回时,释放函数本地变量的内存非常简单 - 它们基本上与函数的堆栈帧一起消失。当它们消失时,它们确实消失了:(在C中(没有办法与他们的消失有关。特别是,对于恰好是文件描述符的变量,无法对close()进行调用。

(如果您想在变量消失时进行清理操作,一种方法是使用C ,使用类变量,并定义一个显式 destructor 。(

当您致电malloc时会出现类似的情况。在此功能中:

void f()
{
    char *p = malloc(10);
}

我们调用malloc分配10个字节的内存,并将返回的指针存储在本地指针变量p中,当功能f返回时,该指针会消失。因此,我们将指向分配的内存的指针丢失了,但是没有呼吁free(),因此存储器仍然分配。(这是内存泄漏的示例。(

最新更新