linux进程描述符、地址空间、文件共享和C语言FILE结构体成员

 对于内核而言,所有打开的文件都通过文件描述符引用,文件描述符是一个非负整数,当打开一个现有文件或或创建一个新文件时,内核向进程返回一个文件描述符,当读或写一个文件时,使用open或creat返回的文件描述符标识该文件,将其作为参数传递给read或write。
 按照惯例,UNIX系统shell使用文件描述符0与进程标准输入相关联,文件描述符1与标准输出相关联,文件描述符2与标准出错相关联,这是各种shell以及很多应用程序使用的惯例,而与UNIX内核无关,如果不遵守这种惯例,那么很多UNIX应用程序就不能正常工作。
 在依从POSIX的应用程序中,幻数0、1、2应当替换成符号常量STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO.这些常量都定义在头文件<unistd.h>中。

这里写图片描述
通过上面的图,我们可以认为文件描述符是文件描述符表的数组下标。

open函数可以打开或创建一个文件
这里写图片描述
pathname是打开或创建文件的名字,flags参数可用来说明此函数的多个选项,用下列一个或多个常量进行“或”运算构成flags参数。
O_RDONLY //只读方式
O_WRONLY //只写方式
O_RDWR //读、写方式

close函数关闭一个文件
这里写图片描述
其参数是该文件的文件描述符
这里写图片描述
成功则返回0,失败则返回-1

read函数
调用read函数从打开文件中读数据。

#include<unistd.h>
ssize_t read(int filedes, void *buf, size_t nbytes);
有多种情况可使实际读到的字节数少于要求读的字节数:
读普通文件时,在读到要求字节数之前已经到达了文件尾端。例如,若在到达文件尾端之前还有30个字节,而要求读100个字节,则read返回30,下一次再调用read时,它将回0。
当从终端设备读时,通常一次最多读一行
当从网络读时,网络中的缓冲机构可能造成返回值小于所要求读的字节数。
当从管道或FIFO读时,如若管道包含的字节少于所需的数量,那么read将只返回实际可用的字节数。
当从某些面向记录的设备(例如磁盘)读时,一次最多返回一个记录。
当某一信号草成终端,而已经读了部分数据量时。读操作从文件的当前偏移量出开始,在成功返回之前,该偏移量将增加实际独到的字节数

write函数
调用write函数向打开的文件写数据。

#include<unistd.h>
ssize_t write(int filedes, const void *buf, size_t nbytes)
对于普通文件,写操作从文件的当前偏移量处开始。如果在打开该文件时,指定了O_APPEND选项,则在每次写操作之前,将文件偏移量设置在文件的当前结尾处。在一次成功写之后,该文件偏移量增加实际写的字节数。

地址空间
我们先来看以下代码:
这里写图片描述
来看运行结果:
这里写图片描述
从结果可以看出,父进程和子进程中的g_val值不同,但地址相同,这是什么原因呢?下面通过一个图来说明:
这里写图片描述
在上面的进程中,fork创建一个子进程即创建了一个新的PCB,两个进程都有一个地址空间(虚拟地址),通过页表将虚拟地址映射到物理地址。父子进程代码共享,数据独立。

fork的一个特性是父进程的所有打开文件描述符都被复制到子进程中。父子进程的每个相同的打开描述符共享一个文件表项,假设一个进程有三个不同的打开文件,在从fork返回时,我们有如下结构:
这里写图片描述

C语言文件操作的底层实现—–FILE结构体
C语言的stdio.h头文件中,定义了用于文件操作的结构体FILE。这样,我们通过fopen返回一个文件指针(指向FILE结构体的指针)来进行文件操作。可以在stdio.h(位于visual studio安装目录下的include文件夹下)头文件中查看FILE结构体的定义,如下:

typedef struct 
 {
     short level;     /* fill/empty level of buffer */
     unsigned  flags;   /* File status flags    */
     char  fd;             /* File descriptor  */
     unsigned char hold;    /* Ungetc char if no buffer */
     short bsize;          /* Buffer size  */
     unsigned char *buffer;   /* Data transfer buffer */
     unsigned char *curp;   /* Current active pointer */
     unsigned istemp;     /* Temporary file indicator */
     short token;        /* Used for validity checking */
}FILE;                  /* This is the FILE object */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值