系统编程-进程-先后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. 进程的状态: 就绪 ...
随机推荐
- 01-初识springboot
目录 01,什么是springboot 02,如何使用springboot 01,什么是springboot springboot是一个基于spring框架开发出来的一个新的框架,目的是为了简化spr ...
- Windows/Linux 安装NVM及npm配置
nvm安装及npm配置 nvm nvm下载 Windows: Releases · coreybutler/nvm-windows (github.com) Windows直接下载相应版本的nvm-s ...
- ComfyUI进阶:Comfyroll插件 (七)
前言: 学习ComfyUI是一场持久战,而Comfyroll 是一款功能强大的自定义节点集合,专为 ComfyUI 用户打造,旨在提供更加丰富和专业的图像生成与编辑工具.借助这些节点,用户可以在静态图 ...
- Jenkins+docker 部署SpringCloud微服务
部署需要提前准备的环境:安装好Jenkins.docker.Maven.Jdk1.8.Git 说明:由于本例只说明如何部署,所以有关项目其他服务如nacos.mysql.redis.seata等默认已 ...
- python os.path 模块详解
python os.path 模块详解 os.path.basename() 返回最后一项,通常是文件名os.path.dirname() 返回的是目录,不包含文件名os.path.split() 返 ...
- 第一讲:日志系统:一条sql更新语句是如何执行的?
目录 第一讲:日志系统:一条sql更新语句是如何执行的? 回顾 抛出问题: 提出思路: 重要的日志模块:redo log 重要的日志模块:binlog 为什么会有两份日志呢? 这两种日志有以下三点不同 ...
- 【JavaWeb】接口请求404的问题排查
响应状态404:404 Page Not Found 根本原因: 服务器找不到这个地址描述的页面资源, 注意是页面资源 可能的出现的开发情况: 1.请求的资源可能真的不存在,是接口,也可以是页面 2. ...
- 【DataBase】MySQL 09 SQL函数 单行函数其三 日期函数
日期函数 日期&时间函数 NOW 当前日期时间. CURDATE 当前日期. CURTIME 当前时间 -- NOW();返回系统日期+时间 SELECT NOW(); -- CURDATE( ...
- 人形机器人 —— NVIDIA公司给出的操作算法(动态操作任务,dynamic manipulation tasks)(机械手臂/灵巧手)框架示意图 —— NVIDIA Isaac Manipulator
原文: https://developer.nvidia.com/isaac/manipulator#foundation-models NVIDIA公司准备针对人形机器人的各部分操作分别推出一个AI ...
- 使用CPU运行大语言模型(LLM),以清华开源大模型ChatGLM3为例:无需显卡!用CPU搞定大模型运行部署!【详细手把手演示】
教程视频地址: 无需显卡!用CPU搞定大模型运行部署![详细手把手演示] 按照上面视频进行安装配置之前需要注意,python编程环境需要大于等于python3.10,否则会运行报错.下载好GitHub ...