区分它们很重要文件描述符,它是一个小整数,进程在读取和写入调用中使用它来标识文件,并且文件描述,这是内核中的一个结构体。文件偏移量是文件描述的一部分。它存在于内核中。
作为示例,让我们使用这个程序:
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
int main(void)
{
int fd;
fd = open("output", O_CREAT|O_TRUNC|O_WRONLY, 0666);
if(!fork()) {
/* child */
write(fd, "hello ", 6);
_exit(0);
} else {
/* parent */
int status;
wait(&status);
write(fd, "world\n", 6);
}
}
(省略了所有错误检查)
如果我们编译这个程序,调用它hello
,然后像这样运行:
./hello
发生的情况如下:
该程序打开output
文件,如果它不存在则创建它,或者如果它存在则将其截断为零大小。内核创建一个文件描述(在 Linux 内核中这是一个struct file
)并将其与调用进程的文件描述符相关联(该进程的文件描述符表中尚未使用的最低非负整数)。文件描述符被返回并分配给fd
在节目中。为了论证的方便,假设fd
is 3.
该程序执行 fork()。新的子进程得到一个copy其父级的文件描述符表,但不复制文件描述。两个进程的文件表中的条目号 3 指向相同的struct file
.
当子进程写入时,父进程等待。孩子的写导致前半部分"hello world\n"
存储到文件中,并将文件偏移量增加 6。文件偏移量位于struct file
!
孩子退出,父母退出wait()
完成,父进程使用 fd 3 进行写入,该文件仍然与相同的文件描述相关联,该文件描述的文件偏移量已由子进程更新write()
。所以消息的后半部分被存储after第一部分,不会像父级文件偏移量为零时那样覆盖它,如果文件描述未共享,就会出现这种情况。
最后父进程退出,内核看到struct file
不再使用并释放它。