系统编程-进程-先后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. 进程的状态: 就绪 ...
随机推荐
- 【Vue】10 Vue-Cli 项目创建
简单的Demo案例并不需要Vue-Cli,因为一个页面之内可以总揽 但是真实的项目开发,考虑代码结构,目录结构,部署,热部署,单元测试... 代码量呈几何倍数增长,而且缺少轮子就写起来很痛苦 所以必须 ...
- vue之循环遍历v-for
1.背景 2.遍历数组 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...
- 重磅预告!Apache DolphinScheduler 3.2.0 新功能“剧透”
近期,Apache DolphinScheduler 将迎来 3.2.0 版本的到来.本次发版为大版本发布,将会带来众多大家期待已久的新功能和新改进.为了让用户提前感知到新版本的变化,社区特意提前&q ...
- 聚焦OLAP性能提升,火山引擎ByteHouse发布六大场景解决方案
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群. 性能在数据分析中至关重要,它直接决定数据处理的效率与及时性,进一步对数据驱动的企业决策造成影响. 举个例 ...
- CF1051F题解
The Shortest Statement 算法:树链剖分,最小生成树,最短路. 先讲一下题意:有一个 \(n\) 点 \(m\) 边的无向连通图,\(q\) 次询问,每次询问 \(a\) 到 \( ...
- 通过JUnit源码分析学习编程的奇技淫巧
打开 Maven仓库,左边选项栏排在第一的就是测试框架与工具,今天的文章,V 哥要来聊一聊程序员必备的测试框架JUnit 的源码实现,整理的学习笔记,分享给大家. 有人说,不就一个测试框架嘛,有必要去 ...
- 与LLMs进行在IDE中直接、无需提示的交互是工具构建者探索的一个有希望的未来方向
这个观点在卡内基梅隆大学与谷歌研究人员合作文章 <Using an LLM to Help With Code Understanding> 中提出. 论文地址:https://dl.ac ...
- 什么是FPGA?为什么FPGA会如此重要?
CPU.GPU.FPGA三者能力相加就是芯片的未来! 很多粉丝问我,嵌入式方向中的FPGA怎么样?收入如何? 前言 讲述FPGA前,我们先讲讲当年中兴被制裁的问题. 美国前总统特朗普曾经发布过一条禁令 ...
- .NET 智能组件完全开源
Daniel Roth在2024年3月20日发布了一篇文章: .NET 智能组件简介 – AI 驱动的 UI 控件.文章主要介绍了.NET Smart Components,这是一系列可以快速轻松地添 ...
- BST 二叉搜索树 BinarySearchTree C++实现(递归/非递归)
目录 二叉搜索树 基本概念 常用结论 用途 二叉搜索树的性能分析 二叉搜索树的操作 查找 插入 删除 代码实现 BSTree.hpp test.cc 二叉搜索树 基本概念 二叉搜索树(BST,Bina ...