Linux內核的文件結構體ui
struct file {
.........
struct path f_path; //文件的路徑
#define f_dentry f_path.dentry
#define f_vfsmnt f_path.mnt
const struct file_operations *f_op;//訪問方式
atomic_long_t f_count; //文件的引用計數,引用計數值爲0時,文件纔會關閉
unsigned int f_flags; //標誌位
mode_t f_mode; //讀寫等權限
loff_t f_pos; //讀到了哪一個位置
struct fown_struct f_owner;
unsigned int f_uid, f_gid; //文件所屬uid,gid
struct file_ra_state f_ra;
u64 f_version;
#ifdef CONFIG_SECURITY
void *f_security;
#endif
/* needed for tty driver, and maybe others */
void *private_data;
.............
};
文件的引用計數,引用計數值爲0時,文件纔會被關閉。atom
兩種情景分析:spa
1.fork()以前就open了文件,而且讀取了部份內容3d
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#include<unistd.h>
#include<sys/wait.h>
#include<fcntl.h>
int main()
{
int fd = open("tmp.txt",O_RDONLY);
assert(fd!=-1);
char buff[10]={0};
pid_t pid = fork();
if(pid == 0){
read(fd,buff,1); //子進程讀1個字節內容
printf("buff = %s\n",buff);
}else if(pid > 0){
sleep(5); //保證子進程能夠先讀文件
read(fd,buff,2); //父進程讀2個字節
printf("buff = %s\n",buff);
wait(NULL); //收屍,不獲取死因
}
close(fd);
return 0;
}
tmp.txt的內容爲「niceday」指針
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/process# gcc process.c -o ab
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/process#
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/process# ./ab
buff = n
buff = ic
小結:code
先open再fork,文件只被打開一次,父子進程共享一個文件描述信息,包括引用計數、讀取位置等等。blog
雖然父子進程都讀取了該文件,因爲文件的引用計數始終爲1,因此只須要close一次便可。繼承
能夠在子進程代碼分支中close,也能夠在父進程代碼分支close,還能夠在公共部分close。進程
子進程複製了父進程的文件表項指針, 指向的是同一個文件表項,以下圖:ci
2.fork()調用以後open文件
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#include<unistd.h>
#include<sys/wait.h>
#include<fcntl.h>
int main()
{
pid_t pid = fork();
int fd = open("tmp.txt",O_RDONLY);
assert(fd!=-1);
char buff[10]={0};
if(pid == 0){
read(fd,buff,1); //子進程讀1個字節內容
printf("buff = %s\n",buff);
}else if(pid > 0){
sleep(5); //保證子進程能夠先讀文件
read(fd,buff,2); //父進程讀2個字節
printf("buff = %s\n",buff);
wait(NULL); //收屍,不獲取死因
}
close(fd);
return 0;
}
tmp.txt的內容爲「niceday」, 同上。
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/process# gcc process.c -o ab
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/process#
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/process# ./ab
buff = n
buff = ni
小結:
此時的文件描述信息再也不是共享的,一個文件被打開了兩次,即引用計數值爲2,每一個進程都有本身的一份,因此兩個進程讀寫操做互不影響。
總結:
先open,再fork:子進程無條件繼承父進程的文件描述信息,子進程和父進程指向同一個文件描述信息。
先fork,再open:子進程有本身的配置,和父進程的配置是相互獨立的關係。所謂配置,例如文件描述信息。
.