系统编程-进程-先后fork或open一个文件的区别
关联博文:
当文件操作遇上fork
Linux内核的文件结构体
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时,文件才会被关闭。
两种情景分析:
1.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()
{
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
小结:
先open再fork,文件只被打开一次,父子进程共享一个文件描述信息,包括引用计数、读取位置等等。
虽然父子进程都读取了该文件,由于文件的引用计数始终为1,所以只需要close一次即可。
可以在子进程代码分支中close,也可以在父进程代码分支close,还可以在公共部分close。
子进程复制了父进程的文件表项指针, 指向的是同一个文件表项,如下图:

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:子进程有自己的配置,和父进程的配置是相互独立的关系。所谓配置,例如文件描述信息。
文末,再来一幅图(不一样的精彩)

.
系统编程-进程-先后fork或open一个文件的区别的更多相关文章
- Linux系统编程@进程通信(一)
进程间通信概述 需要进程通信的原因: 数据传输 资源共享 通知事件 进程控制 Linux进程间通信(IPC)发展由来 Unix进程间通信 基于System V进程间通信(System V:UNIX系统 ...
- linux服务器开发二(系统编程)--进程相关
进程相关的概念 程序与进程 程序,是指编译好的二进制文件,在磁盘上,不占用系统资源(CPU.内存.打开的文件.设备.锁等等). 进程,是一个抽象的概念,与操作系统原理联系紧密.进程是活跃的程序,占用系 ...
- linux系统编程-进程
进程 现实生活中 在很多的场景中的事情都是同时进行的,比如开车的时候 手和脚共同来驾驶汽车,再比如唱歌跳舞也是同时进行的: 如下是一段视频,迈克杰克逊的一段视频: http://v.youku.com ...
- (C#)Windows Shell 编程系列1 - 基础,浏览一个文件夹
原文 (C#)Windows Shell 编程系列1 - 基础,浏览一个文件夹 (本系列文章由柠檬的(lc_mtt)原创,转载请注明出处,谢谢-) Windows Shell 编程,即 Windows ...
- Linux系统编程@进程管理(一)
课程目标: 构建一个基于主机系统的多客户即时通信/聊天室项目 涉及的理论知识 进程控制:僵尸进程/孤儿进程.进程控制.守护进程... 进程间通信:管道.命名管道.信号... 多线程编程: 锁.信号量. ...
- Linux系统编程@进程管理(二)
1.创建守护进程(Deamon) 守护进程的概念与作用 后台服务程序 – 系统服务,进程名字往往以’d’结尾,生存周期比较长(系统装入时启动,关闭时候终止.系统装入两种启动方式:1从启动脚本.etc/ ...
- [linux] C语言Linux系统编程进程基本概念
1.如果说文件是unix系统最重要的抽象概念,那么进程仅次于文件.进程是执行中的目标代码:活动的.生存的.运行的程序. 除了目标代码进程还包含数据.资源.状态以及虚拟化的计算机. 2.进程体系: 每一 ...
- 《Linux/Unix系统编程手册》读书笔记8 (文件I/O缓冲)
<Linux/Unix系统编程手册>读书笔记 目录 第13章 这章主要将了关于文件I/O的缓冲. 系统I/O调用(即内核)和C语言标准库I/O函数(即stdio函数)在对磁盘进行操作的时候 ...
- (C#)Windows Shell 外壳编程系列1 - 基础,浏览一个文件夹
1 - 基础,浏览一个文件夹 我们知道,在win32中是以外壳名字空间的形式来组织文件系统的,在外壳名字空间里的每一个对象(注)都实现了一个IShellFolder的接口,通过这个接口我们可以直接查询 ...
- Linux系统编程-----进程fork()
在开始之前,我们先来了解一些基本的概念: 1. 程序, 没有在运行的可执行文件 进程, 运行中的程序 2. 进程调度的方法: 按时间片轮转 先来先服务 短时间优先 按优先级别 3. 进程的状态: 就绪 ...
随机推荐
- 企业级环境部署:在 Linux 服务器上如何搭建和部署 Python 环境?
在大部分企业里,自动化测试框架落地都肯定会集成到Jenkins服务器上做持续集成测试,自动构建以及发送结果到邮箱,实现真正的无人值守测试. 不过Jenkins搭建一般都会部署在公司的服务器上,不会在私 ...
- 题解:P10723 [GESP202406 七级] 黑白翻转
背景 汗流浃背了. 分析 容易想到一个显然的思路:以任意节点为根,开始遍历.如果一个节点的子树里面有黑点,那么它必须保留,否则如果它是白点,则可以删去. 但这个方法很容易举出反例: 在这颗树中,如果以 ...
- C#/.NET这些实用的编程技巧你都会了吗?
DotNet Exercises介绍 DotNetGuide专栏C#/.NET/.NET Core编程常用语法.算法.技巧.中间件.类库练习集,配套详细的文章教程讲解,助你快速掌握C#/.NET/.N ...
- wails实现腾讯元器bot
简单记录工具的一个模块 后端 Api调用 登录 腾讯元器 后创建智能体,按自己的需求来创建,发布后要等等审核. 等发布完成后点击调用api即可,这里可以看到user_id, assistant ...
- Android SDK Build-tools的版本已经高于Android SDK Platform-tools版本 的解决办法
解决Unknown error: Unable to build: the file dx.jar was not loaded from the SDK folder!最近渐渐迁移到Android ...
- 全网最好看的单细胞umap图绘制教程
全网最好看的单细胞umap图绘制教程 作者按 大家或许都曾被Nature, Science上的单细胞umap图吸引过,不免心生崇拜.在这里,我们将介绍一种简单方便的顶刊级umap图可视化 全文字数|预 ...
- 浅谈Git架构和如何避免代码覆盖的事故
浅谈Git架构和如何避免代码覆盖的事故 Git 不同于 SVN 的地方在于, Git 是分布式的版本管理系统, 所有的客户端和服务器都保存了一份代码, 涉及到仓库仓之间的同步, 所以处理不当极易造成冲 ...
- 轻量级SpringBoot Office文档在线预览框架
框架简介 介绍:基于开源项目KkFileView源码提取出,封装成仅用于 Office文档预览(格式转换) 功能的一个通用组件; 原理是把Word转成PDF,PPT转成PDF,Excel转成HTML; ...
- 为团队配置Linux环境,简单高效的项目共享方案
前言 最近好久没写博客了,事情太多了,我还搞了个新的好玩的项目,等后续做得差不多了来写篇文章介绍一下. 在我们目前的AI项目中,团队需要共同使用一台GPU服务器来做模型训练和数据处理.为了让每个团队成 ...
- 【VMware】将NAT虚拟机开放访问
NAT模式下面需要将主机内的虚拟机提供给外部访问 这个设置可以通过开启端口来实现外部访问NAT虚拟机 主机端口 - 映射 虚拟机 IP 的端口,问题是有多少个虚拟机应用就需要开多少个端口...