系统编程-进程-当文件操作遇上fork
我的关联博文:
系统编程-进程-fork深度理解、vfork简介
系统编程-进程-先后fork或open一个文件的区别
test1: lseek基本使用
#include <stdio.h> #include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> #include <unistd.h> #include <string.h> char string_buf[] = "hello"; char char_H = 'H'; int main(){ int fd = open("file.txt", O_CREAT|O_RDWR|O_TRUNC, S_IRWXU); printf("sizeof(string_buf) = %ld \n", strlen(string_buf)); ssize_t bytes_done = write(fd, string_buf, strlen(string_buf));
printf("bytes_done = %ld \n", bytes_done);
// 创建新文件,向该新文件写入5个字节的字符串。 off_t offset = lseek(fd, 10, SEEK_END);
printf("offset = %ld \n", offset);
// 偏移到文件末尾+10字节位置处,也就是说,
// 下一次将写入的位置是该文件的第16字节位置处(从文件的第1字节位置开始计算) ssize_t add_1_byte = write(fd, &char_H, 1);
printf("add_1_byte = %ld \n", add_1_byte);
// 在该文件的第16字节处写入一个ascii字符‘H’ close(fd); return 0;
}
探究父子进程的文件描述符、文件表项、I节点,
以lseek+fork实验为切入点进行分析。
实验思路:
做两个实验,一是先fork,父进程先lseek后, 子进程才write,观察子进程写入该文件的偏移在哪。
再一个实验是,先lseek,然后才fork。
test2
探究父子进程的文件描述符、文件表项、I节点
以lseek+fork实验为切入点进行分析
实验思路:先fork,父进程先lseek后, 子进程才write,观察子进程写入该文件的偏移在哪。
#include <stdio.h> #include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> #include <unistd.h> #include <string.h> char string_buf[] = "hello"; char char_H = 'H'; int main(){ int fd = open("file.txt", O_CREAT|O_RDWR|O_TRUNC, S_IRWXU); printf("sizeof(string_buf) = %ld \n", strlen(string_buf)); ssize_t bytes_done = write(fd, string_buf, strlen(string_buf));
printf("bytes_done = %ld \n", bytes_done);
// 创建新文件,向该新文件写入5个字节的字符串。 pid_t pid = fork();
if(pid < 0){
perror("fork "); }else if( pid > 0){ off_t offset = lseek(fd, 10, SEEK_END);
printf("offset = %ld \n", offset);
// 偏移到文件末尾+10字节位置处,也就是说,
// 下一次将写入的位置是该文件的第16字节位置处(从文件的第1字节位置开始计算) }else{
sleep(1); ssize_t add_1_byte = write(fd, &char_H, 1);
printf("add_1_byte = %ld \n", add_1_byte);
// 在该文件的第16字节处写入一个ascii字符‘H’ } close(fd); return 0;
}
编译运行:
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/fork/当
文件操作遇上fork# gcc test.c
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/fork/当
文件操作遇上fork# ./a.out
sizeof(string_buf) = 5
bytes_done = 5
offset = 15
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/fork/当
文件操作遇上fork# add_1_byte = 1
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/fork/当
文件操作遇上fork# hexdump -C -n 100 file.txt
00000000 68 65 6c 6c 6f 00 00 00 00 00 00 00 00 00 00 48 |hello..........H|
00000010
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/fork/当文件操作遇上fork#
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/fork/当文件操作遇上fork#
实验现象: 父进程在fork前打开了文件,父进程先执行lseek, 子进程延时1秒后才执行写文件,则会受父进程刚才的lseek操作影响。
小结: 文件偏移量这一信息记录在内核的文件表项中,父子进程有自己独立的文件描述符表,但是共享文件表项和I节点。
本实验父子进程实际上操作的是同一个文件表项,所以才产生了这种现象。
test3
探究父子进程的文件描述符、文件表项、I节点
以lseek+fork实验为切入点进行分析
实验思路:先lseek,然后才fork...
#include <stdio.h> #include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> #include <unistd.h> #include <string.h> char string_buf[] = "hello"; char char_H = 'H'; char char_L = 'L'; int main(){ int fd = open("file.txt", O_CREAT|O_RDWR|O_TRUNC, S_IRWXU); printf("sizeof(string_buf) = %ld \n", strlen(string_buf)); ssize_t bytes_done = write(fd, string_buf, strlen(string_buf));
printf("bytes_done = %ld \n", bytes_done);
// 创建新文件,向该新文件写入5个字节的字符串。 off_t offset = lseek(fd, 10, SEEK_END);
printf("offset = %ld \n", offset);
// 偏移到文件末尾+10字节位置处,也就是说,
// 下一次将写入的位置是该文件的第16字节位置处(从文件的第1字节位置开始计算) pid_t pid = fork();
if(pid < 0){
perror("fork "); }else if( pid > 0){ ssize_t add_1_byte = write(fd, &char_L, 1);
printf("add_1_byte = %ld \n", add_1_byte);
// 在该文件的第16字节处写入一个ascii字符‘H’ }else{
sleep(1); ssize_t add_1_byte = write(fd, &char_H, 1);
printf("add_1_byte = %ld \n", add_1_byte);
// 在该文件的第16字节处写入一个ascii字符‘H’ } close(fd); return 0;
}
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/fork/当文件操作遇上fork# gcc test.c
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/fork/当文件操作遇上fork# ./a.out
sizeof(string_buf) = 5
bytes_done = 5
offset = 15
add_1_byte = 1
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/fork/当文件操作遇上fork# add_1_byte = 1
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/fork/当文件操作遇上fork# hexdump -C -n 100 file.txt
00000000 68 65 6c 6c 6f 00 00 00 00 00 00 00 00 00 00 4c |hello..........L|
00000010 48 |H|
00000011
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/fork/当文件操作遇上fork#
小结: 同上一个实验。即:
文件偏移量这一信息记录在内核的文件表项中,父子进程有自己独立的文件描述符表,但是共享文件表项和I节点。
本实验父子进程实际上操作的是同一个文件表项,所以才产生了这种现象。
内核文件结构:

本博文test2、test3中,父子进程操作同一个文件表项,如下图所示

.
系统编程-进程-当文件操作遇上fork的更多相关文章
- Linux系统编程@进程通信(一)
进程间通信概述 需要进程通信的原因: 数据传输 资源共享 通知事件 进程控制 Linux进程间通信(IPC)发展由来 Unix进程间通信 基于System V进程间通信(System V:UNIX系统 ...
- linux系统编程-进程
进程 现实生活中 在很多的场景中的事情都是同时进行的,比如开车的时候 手和脚共同来驾驶汽车,再比如唱歌跳舞也是同时进行的: 如下是一段视频,迈克杰克逊的一段视频: http://v.youku.com ...
- linux服务器开发二(系统编程)--进程相关
进程相关的概念 程序与进程 程序,是指编译好的二进制文件,在磁盘上,不占用系统资源(CPU.内存.打开的文件.设备.锁等等). 进程,是一个抽象的概念,与操作系统原理联系紧密.进程是活跃的程序,占用系 ...
- Linux系统编程@进程管理(一)
课程目标: 构建一个基于主机系统的多客户即时通信/聊天室项目 涉及的理论知识 进程控制:僵尸进程/孤儿进程.进程控制.守护进程... 进程间通信:管道.命名管道.信号... 多线程编程: 锁.信号量. ...
- Unix系统编程()文件描述符和打开文件之间的关系
目前学习到的是一个文件描述符对应着一个打开的文件,似乎是对应的关系.但是实际上并不是这样的.多个文件描述符指向同一个打开的文件,是可能的也是必要的.这些文件描述符可以在相同或者不同的进程中打开. 要理 ...
- python常用标准库(os系统模块、shutil文件操作模块)
常用的标准库 系统模块 import os 系统模块用于对系统进行操作. 常用方法 os模块的常用方法有数十种之多,本文中只选出最常用的几种,其余的还有权限操作.文件的删除创建等详细资料可以参考官方文 ...
- Linux系统编程@进程管理(二)
1.创建守护进程(Deamon) 守护进程的概念与作用 后台服务程序 – 系统服务,进程名字往往以’d’结尾,生存周期比较长(系统装入时启动,关闭时候终止.系统装入两种启动方式:1从启动脚本.etc/ ...
- hadoop的hdfs文件操作实现上传文件到hdfs
这篇文章主要介绍了使用hadoop的API对HDFS上的文件访问,其中包括上传文件到HDFS上.从HDFS上下载文件和删除HDFS上的文件,需要的朋友可以参考下hdfs文件操作操作示例,包括上传文件到 ...
- [linux] C语言Linux系统编程进程基本概念
1.如果说文件是unix系统最重要的抽象概念,那么进程仅次于文件.进程是执行中的目标代码:活动的.生存的.运行的程序. 除了目标代码进程还包含数据.资源.状态以及虚拟化的计算机. 2.进程体系: 每一 ...
- day11 文件操作(上)
目录 一.什么是文件 二.为何要用文件 三.如何使用文件 3.1文件操作的基本流程 3.2资源回收with上下文管理 3.3指定操作文本的字符编码 四.文件的操作模式 4.1控制文件读写操作的模式(t ...
随机推荐
- [oeasy]python0017_解码_decode_字节序列_bytes_字符串_str
解码 decode 回忆上次内容 code就是码 最早也指电报码 后来有各种编码.密码.砝码.条码 都指的是把各种事物编个号 encode就是编码 编码就是给事物编个号 编辑 编码基本了解了 ...
- 使用.NET6实现动态API
ApiLite是基于.NET6直接将Service层生成动态api路由,可以不用添加Controller,支持模块插件化,在项目开发中能够提高工作效率,降低代码量. 开发环境 .NET SDK 6.0 ...
- 单细胞测序最好的教程(十四)测序原始数据公开至NCBI数据库
作者按 国内对于单细胞测序相关的中文教程确实不够全面,当然NCBI官网给的上传教程也比较详细了,所以变成了会者不难.本教程你现在可能用不上,但是你如果做单细胞测序,那么未来你一定会用上,建议收藏. 在 ...
- 【IDEA】转大小写快速操作
需求场景: 快速修改一些字符全部变成大写,或者小写 例如修改SQL语句,部分字段大写,部分字段小写,需要统一 快捷键: [Ctrl + Shift + U] 演示案例: SELECT ( (SELEC ...
- 【ECharts】02 饼图
饼状图: <!-- 为ECharts准备一个具备大小(宽高)的Dom --> <div id="main" style="width: 600px;he ...
- 【Layui】06 面板 Panel
文档地址: https://www.layui.com/doc/element/panel.html 演示案例: <div class="layui-collapse"> ...
- 英语词汇:simplistic和simple区别
"Simplistic" 和 "simple" 都表示简单,但它们有不同的含义和语境: Simplistic: 含义: 过于简单化的,有贬义,表示忽略了复杂性或 ...
- Jax框架的Traced object特性与TensorFlow的placeholder的一致性
前文: Jax框架的static与Traced Operations -- Static vs Traced Operations 前文讨论分析了Jax的static特性和Traced特性,这些谈下个 ...
- 【转载】sun的rpc ——rpcbind(nfs文件系统中的rpc)
原文地址: https://blog.csdn.net/wangpeng138375/article/details/8169071 ================================= ...
- boulanni / theano-hf
https://github.com/boulanni/theano-hf https://people.duke.edu/~hpgavin/ExperimentalSystems/lm.pdf ht ...