当前位置: 首页 > 编程日记 > 正文

[转] linux系统文件流、文件描述符与进程间关系详解

http://blog.sina.com.cn/s/blog_67b74aea01018ycx.html

linux(unix)进程与文件的关系错综复杂,本教程试图详细的阐述这个问题。
包括:
    1、linux多/单进程与多/单文件对于文件流和描述符在使用时的关联情况及一些需要注意的问题。
    2、fork,vfork流缓冲等对文件操作的影响。
 
1、linux文件系统结构
首先补充一点基础知识,了解一下linux文件系统。如下图所示:
磁盘、分区和文件系统
                                                    图1 磁盘,分区和文件系统
 应该明白,上图所示结构是硬盘中文件存放方式的一种逻辑表现形式,与进程无关。对于其中一些术语,见下面的解释。
i节点:包含文件/目录的几乎全部-适用于放置在硬盘上的,需要长久保存的信息。
例如:文件所有者,文件类型,i节点号(存放在目录块中),主次设备号,连接计数,访问/修改时间,IO块长,文件字节数等等。
可以用stat函数(#include )获取相关i节点信息信息。
 
 
2、简单的进程与文件关系
 
下面,我们了解一下单进程多文件以及多进程单文件间的关系,在不考虑fork(父子进程)的情况下,除了赋值语句给我们带来一些小麻烦以外,这个问题还是相当容易的。
 
2.1、一个进程同时打开多个文件:
2
                               图2 一个进程同时打开2个不同文件时内核数据结构
      其中,v节点我们几乎已经介绍过了,因为它除了包含i节点之外,自身的内容实在是不怎么多,重点看一下文件表吧。
      对于文件表,要注意,它并不是从在于硬盘中的东西,可以说,他是进程的一部分(可能是由操作系统内核负责维护,本人未考证(确实是由内核负责维护的,参见APUE->Section3.12),因为它到底是进程的还是内核的,对于我们要探讨的问题无关紧要)。文件表包括:
文件状态标志:包含读,写,添写,同步和非阻塞等各种文件打开/当前状态。
  当前文件偏移量:记录文件指针位置
   V节点/I节点:文件类型和对此文件进行各种操作的函数的指针,这些信息都是在打开文件时候由磁盘读入内存的。
可用fcntl函数(#include )修改文件表内容。
 
 
2.2、多个无关联进程同时打开一个文件:
3                    
                图3 两个进程同时打开同一个文件时内核数据结构
    此时,2个文件分别使用不同的文件表,这说明不同进程间文件状态标志,文件偏移量等都是独立的。但他们共用同一个v节点表。对于这种结构的特性,理解起来因该是个轻松的事情。
 
3、文件描述符或流的复制
对于文件描述符或流的复制,很多情况我们会采用赋值语句,下面了解一个赋值和dup的不同之处,dup函数复制文件描述符后的内核数据结构:
( 文件流和文件描述符的转换见这里
4       
          图4 执行dup函数(#include )复制文件描述符后,内核数据结构。
    此时,2个fd文件标志同时使用同一文件表。
 
 
3.1dup与赋值语句用于文件描述符的区别
 为了了解dup与赋值语句用于文件描述符的区别,请看如下程序。  
程序描述:
    打开一个文件描述符,分别适用dup和赋值语句进行复制,复制之后,打印原始和被复制的文件描述符id,看看是否具有相同的值,然后关闭文件,测试关闭是否成功。
程序示例:
#include
#include
#include
#include
int sys_err(char *str)
{
puts(str);
exit(0);
}
int main(void)
{
int p,q;
if((p=open("c_fid.c", O_RDONLY)) == -1)
sys_err("open error");
q = dup(p);
puts("dup:");
printf("file p,q fd is:%d %d\n", q, p);
printf("close file p ok?: %d\n", close(p));
printf("close file q ok?: %d\n", close(q));
if((p=open("c_fid.c", O_RDONLY)) == -1)
sys_err("open error");
q = p;
puts("=:");
printf("file p,q fd is:%d %d\n", q, p);
printf("close file p ok?: %d\n", close(p));
printf("close file q ok?: %d\n", close(q));
return 0;
}
程序运行结果:
dup:
file p,q fd is:4 3   //文件p,q使用不同的文件描述符
close file p ok?: 0
close file q ok?: 0 //文件关闭成功
=:
file p,q fd is:3 3 //简单复制
close file p ok?: 0
close file q ok?: -1//关闭失败,原因是此描述符已经被关闭了
 
    由此证明,dup是产生一个新的文件描述符id和指针,但是他们共用文 件表,效果如图4,这时,关闭一个文件描述符,另外一个仍旧可用,文件表并不会被释放。而赋值语句不同,它只是简单的在另外一个变量中记录原始文件指针 等,2个变量的文件描述符相同,进程表项中并不产生新的项目。
 
3.2、赋值语句复制标准流。
例:
#include
#include
int sys_err(char *str)
{
puts(str);
exit(0);
}
int main(void)
{
FILE *p,*q;
if((p=fopen("c_fid.c", "r")) == NULL)
sys_err("open error");
q = p;
printf("FILE p,q fd is:%d %d\n", fileno(q),fileno(p));
printf("close file p ok?: %d\n", fclose(p));
printf("close file q ok?: %d\n", fclose(q));
return 0;
}
程序执行结果:
FILE p,q fd is:3 3 //2个流共用同一个文件描述符
close file p ok?: 0
*** glibc detected ***//2次关闭引起错误,造成程序崩溃。
…………
 
 
4、 引入fork后进程与文件关系以及流缓冲对文件操作的影响
4.1 fork
5         
                          图5 使用fork之后,父进程、子进程之间对打开文件的共享
   使用fork后,子进程会继承父进程所打开的文件表,此时,父子进程使用同一个文件 表(可见,上面猜测文件表由内核维护因该是正确的,因为文件表并没有被复制),这说明2个进程将共用文件状态,文件偏移量等信息。如果使用close关闭 一个进程中的文件描述符,那么另一个进程中,此描述符仍然有效,相应文件表也不会被释放。
    需要注意的是,在使用c标准io进行文件读写时,先结束的进程会将缓冲区内数据也计入文件偏移量的长度,对于相应文件缓冲区类型和长度,可以使用setbuf,setvbuf(#include )设置。
程序示例:
#include
#include
#include
#include
#include
int main(void)
{
int pid;
FILE *p;
char buff[20]={0};
int test=-2;
if((p=fopen("/media/lin_space/soft/netbeans-6.5-ml-cpp-linux.sh", "r")) == NULL)
{//文件大于4096字节
puts("open error.");exit(0);
}
if((pid=fork()) < 0)
{
puts("fork error");
exit(0);
}
else if(pid == 0)
{
sleep(2);
test = ftell(p);//返回当前偏移量
printf("\nchild - ftell is: %d\n", test);
if((buff[0] = fgetc(p)) != EOF)
printf("child - fgetc is: %c\n", buff[0]);
else
puts("child - fgetc error\n");
test = ftell(p);
printf("child - ftell is: %d\n", test);
}
else
{
test = ftell(p);
printf("\nparent - ftell is: %d\n", test);
if((buff[0] = fgetc(p)) != EOF)
printf("parent - fgetc is: %c\n", buff[0]);
else
puts("parent - fgetc error\n");
test = ftell(p);
printf("parent - ftell is: %d\n", test);
}
printf("parent and child - close file ok?: %d\n", fclose(p));
return 0;
}
程序执行结果:
parent - ftell is: 0
parent - fgetc is: #
parent - ftell is: 1
parent and child - close file ok?: 0
freec@freec-laptop:/media/lin_space/summa/apue/unit8$     //父进程结束
child - ftell is: 4096     //子进程文件偏移量为4096,原因是文件缓冲类型为全缓冲,缓冲区大小为4096
child - fgetc is: a
child - ftell is: 4097
parent and child - close file ok?: 0     //文件关闭成功
4.2 vfork
    而对于vfork,虽然子进程运行于父进程的空间,但是子进程却拥有自己的进程表项(包含进程pid,fd标志,文件指针等),所以,在其中一个进程结束后,另外一个进程的文件描述符依旧有效,子进程得到的是父进程文件描述符的副本。
    但是vfork对于标准流,情况则不同,一个进程结束后(如果不是使用_exit()结束进程),则此进程结束时可能会冲洗流缓冲区,并且关闭流,对于是否这样做,要取决于具体实现
  fork与vfork的区别见这里

转载于:https://www.cnblogs.com/qiangxia/p/4243769.html

相关文章:

VMware虚拟机 取消 简易安装

我的VMware更新到12.0版本了&#xff0c;突然有了个简易安装操作系统&#xff0c;不得不承认这个功能很省事&#xff0c;如果没有特殊要求&#xff0c;这样安装虚拟机既快速有稳定。 但是专业人士总是要专门的服务&#xff0c;追求自动化&#xff0c;往往忽略一些细节上的东西。…

UE5蓝图初学课程 Unreal Engine 5: Blueprints for Beginners

时长:6h 51m |视频:. MP4 1280720&#xff0c;30 fps(r) |音频:AAC&#xff0c;44100 Hz&#xff0c;2ch |大小解压后:4.4 GB 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; 没有编码的游戏开发 开发一个高质量的游戏&#xff0c;不需要写…

SQL基础学习总结:1(数据库)

数据库 我们通常将可以将大量数据保存下来&#xff0c;通过计算机加工而成的可以进行高效访问的数据集合称为数据库&#xff0c;简称&#xff1a;DB。 而用来管理数据库的计算机系统则称之为数据库管理系统&#xff0c;简称&#xff1a;DBMS。一般情况下&#xff0c;系统的使用…

MyEclipse安装Freemarker插件

以下是安装Freemarker插件并设置MyEclipse使用该插件的步骤&#xff1a;1、下载Freemarker插件 打开http://sourceforge.net/projects/freemarker-ide/files/ 2、解压&#xff0c;将hudson.freemarker_ide_0.9.14文件夹放入eclipse下的plugins文件夹。 发现hudson.freemarker_…

单例模式为什么使用volatile,以及双重检查&单例模式的一些思考

也就是第一个if(singleton==null),这个是为了代码提高代码执行效率,由于单例模式只要一次创建实例即可,所以当创建了一个实例之后,再次调用getInstance方法就不必要进入同步代码块,不用竞争锁。直接返回前面创建的实例即可。

2022-2028年中国IT外包市场投资分析及前景预测报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国IT外包行业市场行业相关概述、中国IT外包行业市场行业运行环境、分析了中国IT外包行业市场…

iOS,Android,WP, .NET通用AES加密算法

这两天为移动App开发API&#xff0c;结果实现加密验证时碰到一大坑。这里不得不吐槽下又臭又硬的iOS&#xff0c;Windows Server无法解密出正确的结果&#xff0c;Android则可以&#xff0c;后来使用了通用的AES256加密算法才最终搞定。 搞服务器端小伙伴没有接触过iOS&#xf…

【Linux】Linux下的硬链接与符号链接

Linux的初学者常常混淆Linux中的硬链接&#xff08;hard link&#xff09;与符号链接&#xff08;symbol link&#xff09;的概念&#xff0c;分不清楚它们的区别。因此&#xff0c;本文将向读者全面介绍硬链接与符号链接&#xff0c;给予读者以全面的认识。 1.Linux下的文件系…

Unity + SQL数据库创建管理玩家排行榜学习教程

Unity SQL Databases Player Management Leaderboards More! Unity SQL数据库玩家管理排行榜更多&#xff01; MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz&#xff0c;2 Ch 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&…

SQL基础学习总结:2(表的创建、删除、更新和名称修改)

表的创建、删除、更新和名称修改 登录MySQL(mysql -u root -p语句) 步骤&#xff1a; 1.首先得先使用mysql -u root -p语句登录数据库&#xff1b; 2.在"Enter password:"后面输入你设置的密码&#xff0c;然后就登录到MySQL可以进行数据库得操作了。 如下图&#…

需要抛出异常的情况

1、调用一个抛出已检查异常的方法。例如FileInputStream构造器。 2、程序运行中发现错误&#xff0c;并且利用throw语句抛出一个已检查异常。 3、程序出现错误。例如a[-1]0会抛出一个ArrayIndexOutOfBoundsException异常。 4、Java虚拟机和运行时库出现的内部错误。 对于可能会…

2022-2028年中国HDPE膜行业市场研究及投资发展分析报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国HDPE膜行业市场行业相关概述、中国HDPE膜行业市场行业运行环境、分析了中国HDPE膜行业市场…

linux+postfix+extmail+dovecot搭建邮件服务器

一、我们可以重新搭建服务器&#xff0c;也可以利用我前面的搭建方法编译安装&#xff0c;地址&#xff1a;http://wangzan18.blog.51cto.com/8021085/1605480&#xff0c;本次我们使用yum的方法来安装httpd和mysql&#xff0c;我的搭建环境还是我们的CentOS6.6 x86-64位mini版…

2009年3月

1、http://www.west-wind.com/Weblog/posts/509108.aspx Client Templating with jQuery http://jtemplates.tpython.com/ jTemplates is a template engine for JavaScript. 2、http://www.cnblogs.com/QLeelulu/archive/2008/11/27/1342722.html jQuery的模板与数据绑定插件…

UE4创建第一人称射击游戏学习教程

Unreal Engine 4: Create Your Own First-Person Shooter MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz&#xff0c;2 Ch 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; |时长:38节课(9h 56m) |大小解压后:6.8 GB 学…

SQL基础学习总结:3(select语句基础算术运算符比较运算符)

select语句基础 列的查询 从表中选取数据时需要使用select语句&#xff0c;通过select语句查询并选取出必要数据的过程称为匹配查询或查询。 语法结构如下&#xff1a; select <列名1>,<列名2>,<列名3>... from <表名>;该select语句包含了select和f…

Linux——Linux概念架构的理解

摘要 Linux kernel成功的两个原因&#xff1a;&#xff08;1&#xff09;灵活的架构设计使得大量的志愿开发者能够很容易加入到开发过程中&#xff1b;&#xff08;2&#xff09;每个子系统&#xff08;尤其是那些需要改进的&#xff09;都具备良好的可扩展性。正是这两个原因使…

2022-2028年中国GPS导航行业投资分析及前景预测报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国GPS导航行业市场行业相关概述、中国GPS导航行业市场行业运行环境、分析了中国GPS导航行业市…

Geohash的精度问题

网上的关于Geohash的精度问题的说明都不够完整&#xff0c;做了一下补充&#xff0c;可以参见本文表格。 具体的计算方法&#xff1a;Latitude的范围是&#xff1a;-90 到 90Longitude的范围&#xff1a;-180 到 180地球参考球体的周长&#xff1a;40075016.68米geohash长度Lat…

在CentOS上把MySQL从5.5升级到5.6

在CentOS上把MySQL从5.5升级到5.6 摘要&#xff1a;本文记录了在CentOS 6.3上&#xff0c;把MySQL从5.5.28升级到5.6.19的过程。 1. 概述 在我做的一个项目中&#xff0c;最近我对生产服务器上的一系列系统软件进行了升级&#xff0c;包括Git、Nginx、MySQL和PHP。这篇文章讲的…

在3ds Max和Vray中创建赛博朋克圣诞老人室内场景

我叫奥马尔萨米罗什迪&#xff0c;建筑师、室内设计师、助理讲师、摄影师和3d艺术家。2019年获得建筑学硕士学位。我曾为多家建筑事务所和顾问工作&#xff0c;甚至建立了自己的建筑工作室。我有很长的大学教学生涯&#xff0c;从2013年开始&#xff1b;我曾在知名大学教授设计…

Java之网络通信框架mina

mina是一个基于java nio的网络通信框架。主要屏蔽了网络通信的一些细节,对Socket进行封装,并且是NIO的一个实现架构,可以帮助我们快速的开发网络通信,常用于游戏的开发、中间件服务端的程序中。Apache的Mina(Multipurpose Infrastructure Networked Applications)是一个网络应用框架,可以帮助用户开发高性能和高扩展性的网络应用程序;它提供了一个抽象的、事件驱动的异步API,使。

GIT常用命令大全

git config --global color.ui true //让git显示颜色//忽略特殊文件//.gitignore文件 # Windows: Thumbs.db*.egg*.egg-infodist//把该文件也提交到git$ git add -f App.class //强制添加被忽略的特殊文件。

SQL基础学习总结:5(HAVING子句的使用ORDER BY排序子句的使用)

为聚合结果指定条件 HAVING子句 HAVING子句可以让我们筛选分组之后的各种数据&#xff0c;其语法结构如下&#xff1a; SELECT <列名1>,<列名2>,<列名3> FROM <表名> GROUP BY <列名1>,<列名2>,<列名3> HAVING <分组结果对应的…

【转】android错误 aapt.exe已停止工作的解决方法

http://www.jb51.net/article/57420.htm 在使用eclipse进行安卓java的编程的时候&#xff0c;有时候我们会遇到这样的问题&#xff1a;那就是无故弹出aapt.exe停止工作的提示&#xff0c;虽然程序不会崩溃&#xff0c;但是这个提示经常弹出很是烦人。今天&#xff0c;小编就来教…

2022-2028年中国FEP薄膜行业市场发展规模及市场分析预测报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国FEP薄膜行业市场行业相关概述、中国FEP薄膜行业市场行业运行环境、分析了中国FEP薄膜行业市…

Android-----View绘制流程以及invalidate()等相关方法分析 .

引自&#xff1a;http://blog.csdn.net/qinjuning/article/details/7110211 前言&#xff1a; 本文是我读《Android内核剖析》第13章----View工作原理总结而成的&#xff0c;在此膜拜下作者 。同时真挚地向渴望了解 Android 框架层的网友&#xff0c;推荐这本书&#xff0c;希望…

实现ASP.NET MVC3 HtmlHelper 的 RadioButtonList 与CheckBoxList 扩展

ASP.NET MVC3也出来有一段时间了&#xff0c;对于没有RadioButtonList 与CheckBoxList的问题&#xff0c;网上也已经有很多解决方案了&#xff0c;可以for循环拼接出来&#xff0c;也可以引用ASP.NET MVC Toolkit&#xff0c;等等方法。其实本没有必要写出来的&#xff0c;不过…

Blender从头到尾创建一个低多边形场景学习教程

Low Poly Landscapes – Blender Bite Sized Course 流派:电子学习| MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;48.0 KHz 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09;|大小解压后:3.9 GB |时长:6h 0m 从头到尾创造一个低聚…

SQL基础学习总结:6(INSERT语句的相关使用方法)

数据的插入(INSERT语句的使用方法) 我们之前在表的创建部分简单地介绍了一下INSERT语句的功能和使用方法&#xff0c;现在我们再详细讲一下它的用法。 INSERT语句的基本语法 其语法结构如下&#xff1a; INSERT INTO <表名> (列名1,列名2,列名3...)-> VALUES (数据…