关联博文:

当文件操作遇上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一个文件的区别的更多相关文章

  1. Linux系统编程@进程通信(一)

    进程间通信概述 需要进程通信的原因: 数据传输 资源共享 通知事件 进程控制 Linux进程间通信(IPC)发展由来 Unix进程间通信 基于System V进程间通信(System V:UNIX系统 ...

  2. linux服务器开发二(系统编程)--进程相关

    进程相关的概念 程序与进程 程序,是指编译好的二进制文件,在磁盘上,不占用系统资源(CPU.内存.打开的文件.设备.锁等等). 进程,是一个抽象的概念,与操作系统原理联系紧密.进程是活跃的程序,占用系 ...

  3. linux系统编程-进程

    进程 现实生活中 在很多的场景中的事情都是同时进行的,比如开车的时候 手和脚共同来驾驶汽车,再比如唱歌跳舞也是同时进行的: 如下是一段视频,迈克杰克逊的一段视频: http://v.youku.com ...

  4. (C#)Windows Shell 编程系列1 - 基础,浏览一个文件夹

    原文 (C#)Windows Shell 编程系列1 - 基础,浏览一个文件夹 (本系列文章由柠檬的(lc_mtt)原创,转载请注明出处,谢谢-) Windows Shell 编程,即 Windows ...

  5. Linux系统编程@进程管理(一)

    课程目标: 构建一个基于主机系统的多客户即时通信/聊天室项目 涉及的理论知识 进程控制:僵尸进程/孤儿进程.进程控制.守护进程... 进程间通信:管道.命名管道.信号... 多线程编程: 锁.信号量. ...

  6. Linux系统编程@进程管理(二)

    1.创建守护进程(Deamon) 守护进程的概念与作用 后台服务程序 – 系统服务,进程名字往往以’d’结尾,生存周期比较长(系统装入时启动,关闭时候终止.系统装入两种启动方式:1从启动脚本.etc/ ...

  7. [linux] C语言Linux系统编程进程基本概念

    1.如果说文件是unix系统最重要的抽象概念,那么进程仅次于文件.进程是执行中的目标代码:活动的.生存的.运行的程序. 除了目标代码进程还包含数据.资源.状态以及虚拟化的计算机. 2.进程体系: 每一 ...

  8. 《Linux/Unix系统编程手册》读书笔记8 (文件I/O缓冲)

    <Linux/Unix系统编程手册>读书笔记 目录 第13章 这章主要将了关于文件I/O的缓冲. 系统I/O调用(即内核)和C语言标准库I/O函数(即stdio函数)在对磁盘进行操作的时候 ...

  9. (C#)Windows Shell 外壳编程系列1 - 基础,浏览一个文件夹

    1 - 基础,浏览一个文件夹 我们知道,在win32中是以外壳名字空间的形式来组织文件系统的,在外壳名字空间里的每一个对象(注)都实现了一个IShellFolder的接口,通过这个接口我们可以直接查询 ...

  10. Linux系统编程-----进程fork()

    在开始之前,我们先来了解一些基本的概念: 1. 程序, 没有在运行的可执行文件 进程, 运行中的程序 2. 进程调度的方法: 按时间片轮转 先来先服务 短时间优先 按优先级别 3. 进程的状态: 就绪 ...

随机推荐

  1. [oeasy]python0072_修改字体前景颜色_foreground_color_font

    修改颜色 回忆上次内容 m 可以改变字体样式 0-9 之间设置的都是字体效果 0 重置为默认 1 变亮 2 变暗 3 斜体 4 下划线 5 慢闪 6 快闪 7 前景背景互换 8 隐藏 9 中划线 叠加 ...

  2. oeasy教您玩转vim - 27 - 文件类型

    ​ 文件类型 回忆上节课内容 上次了解了缩进的各种方式 正常模式下用 << 缩进 插入模式下用 tab 缩进 显示缩进情况 :set listchars=eol:$,tab:>-,s ...

  3. SQL Server调用OLE对象

    T-SQL 中是可以调用 OLE 的,将这一功能应用到触发器.存储过程等对象中,SQL Server 运用变得更贴近我们的功能,更加满足我们的需要. T-SQL 中有七个存储过程是围绕本节内容进行的, ...

  4. Win10下安装LabelImg以及使用--LabelImg

    labelImg是图片标注软件,用于数据集的制作.标注等等.下面介绍labelImg的安装过程. 我用的是anaconda,所以以anaconda prompt作为终端: 在Anaconda Prom ...

  5. DASCTF 2023六月挑战赛|二进制专项 PWN (下)

    DASCTF 2023六月挑战赛|二进制专项 PWN (下) 1.can_you_find_me 检查保护 意料之中 64位ida逆向 只有add,和del功能不能show 先看add吧 最多申请10 ...

  6. hbuilderx打正式包所需的私钥证书的创建方法

    现在使用uniapp作为底层框架来开发app应用已经成为了很多公司的事实标准,而uniapp的开发工具hbuilderx云打包的时候,需要私钥证书和证书profile文件. 而且还需要将打包好的ipa ...

  7. 【Java】利用反射更改String的字符

    问题: 在不改变s变量引用的String对象的情况下,输出打印"abcd" /*** * * @param args * @return void * @author cloud9 ...

  8. 【Spring】02 过程分析

    回顾JavaWeb三层架构设计: UserDao接口 public interface UserDao { void getUser(); } 实现类 public class UserDaoImpl ...

  9. 【RabbitMQ】06 Spring整合RabbitMQ

    首先生产者和消费者需要的Maven依赖是一样的 <?xml version="1.0" encoding="UTF-8"?> <project ...

  10. 跨平台字幕制作软件ARCTIME

      官网:http://arctime.cn/