c - 文件描述符存储在进程内存中的什么位置?

标签 c linux memory-management file-descriptor

当从一个执行点调用函数A时,内部是JMP语句指向函数A的地址。所以当前执行点被保存到栈上,PC加载被调用函数的地址A 并继续。

要在函数调用后回到执行点,函数 block 应该有相等的压入和弹出到堆栈中。通常在 C 中退出函数时,定义的堆栈变量被销毁(我认为这意味着从堆栈中弹出),但我决定在我的函数中定义一个文件描述符变量。代码如下:

void main() {
    printf("In the beginning there was main()\n");
    func_call();
    printf("func_call complete\n");
    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

我检查了文件描述符的维基百科条目,我发现了这个:

To perform input or output, the process passes the file descriptor to the kernel through a system call, and the kernel will access the file on behalf of the process. The process does not have direct access to the file or inode tables.

从上面的语句可以明显看出,文件描述符整数值存储在进程内存中,但尽管它是在函数中定义的,但文件描述符不是函数本地的,因为它在函数退出时没有被删除。

所以我的问题有两个:

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()?您是否希望在 foo 退出后无法再使用 global_fd

在这种情况下,将文件描述符视为指针会很有帮助,您要求内核为您提供文件,它会为您提供一个值,您可以将其用作该特定文件的标记,这token 是你用来让内核知道像 readlseek 这样的函数应该作用于哪个文件。当 token 被传递或销毁时,文件保持打开状态,就像销毁指针不会释放分配的内存一样。

关于c - 文件描述符存储在进程内存中的什么位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44255144/

相关文章:

c - 调用c函数时出现段错误

linux - 如何在 linux mint 中开始使用 swi-prolog

java - Linux从java中查找命令不起作用

c - C语言中带\0的字符串长度

c - 无论内容如何,​​写入给定字节数的字符串

c++ - c/c++ 中的文件压缩/数据损坏检查

linux 终端输出

memory - 堆/栈和多进程

objective-c - 非 GC 应用程序中的内存管理 OS X __block 变量分配

c++ - 删除数组指针?