我的关联博文:

系统编程-进程-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的更多相关文章

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

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

  2. linux系统编程-进程

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

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

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

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

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

  5. Unix系统编程()文件描述符和打开文件之间的关系

    目前学习到的是一个文件描述符对应着一个打开的文件,似乎是对应的关系.但是实际上并不是这样的.多个文件描述符指向同一个打开的文件,是可能的也是必要的.这些文件描述符可以在相同或者不同的进程中打开. 要理 ...

  6. python常用标准库(os系统模块、shutil文件操作模块)

    常用的标准库 系统模块 import os 系统模块用于对系统进行操作. 常用方法 os模块的常用方法有数十种之多,本文中只选出最常用的几种,其余的还有权限操作.文件的删除创建等详细资料可以参考官方文 ...

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

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

  8. hadoop的hdfs文件操作实现上传文件到hdfs

    这篇文章主要介绍了使用hadoop的API对HDFS上的文件访问,其中包括上传文件到HDFS上.从HDFS上下载文件和删除HDFS上的文件,需要的朋友可以参考下hdfs文件操作操作示例,包括上传文件到 ...

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

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

  10. day11 文件操作(上)

    目录 一.什么是文件 二.为何要用文件 三.如何使用文件 3.1文件操作的基本流程 3.2资源回收with上下文管理 3.3指定操作文本的字符编码 四.文件的操作模式 4.1控制文件读写操作的模式(t ...

随机推荐

  1. PowerShell 基本使用

    PowerShell Basic PowerShell Basic 简要 基本使用 PowerShell cmdlet 获取帮助 PowerShell 别名和参数 编写一个 PowerShell 脚本 ...

  2. 解决: Cannot load information for github.com

    问题在共享项目至idea时候出现:I am getting this error while sharing on GithHub in Intellije IDEA : Cannot load in ...

  3. App如何利用推送消息有效实现拉新促活?

    对于大多数App来说,如何快速建立与用户的联系.提高用户活跃度.提升用户转化率,是产品运营过程中十分关心的问题,在常见的运营手段中,Push推送消息以其高性价比成为首选策略.但在实际运营过程中,推送消 ...

  4. java8interface的新特性:default,static,funcation

    default:默认方法 在类接口中可以直接定义的方法,实现接口的类可以直接使用 使用案例: public interface MyInterface { default void display() ...

  5. 【DataBase】MySQL 04 图形化用户界面管理工具

    参考至视频:P16 - P18 https://www.bilibili.com/video/BV1xW411u7ax?p=82 SQL图形化界面管理工具 - SQLyog 随便找的一个下载地址[安装 ...

  6. 【Java-GUI】10 Swing05 JTree

    简单的Tree结构: package cn.dzz; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; pub ...

  7. NVIDIA公司在实体机器人上的第一步尝试 —— Nova Cater AMR —— 九号机器人与英伟达联合开发的自动驾驶研发平台“Nova Cater AMR(简称:NC)”

    相关: https://www.leiphone.com/category/robot/Hgy9i8azqGncESIB.html Nova Cater AMR是一款仓储运货机器人,可以应用在仓储物流 ...

  8. "观察者" 网站上不错的对社会问题进行思考的文章--------------- 分享

    原文地址:      https://www.guancha.cn/weichengling 在网上无意中到了下面的文章,对社会热点问题有较为全面的思考,感觉不错,分享一下. ------------ ...

  9. 【转载】 5:0!AI战胜人类教官,AlphaDogfight大赛落幕

    原文:https://baijiahao.baidu.com/s?id=1675621109599102721&wfr=spider&for=pc ------------------ ...

  10. 关于vue按需引入ElMessage和ElMessageBox未被自动引入到auto-important的问题

    相信关于按需引入大家应该都会了,不论是官网还是百度一大堆教程 我这边也是参照https://github.com/youlaitech/vue3-element-admin的写法去写的-----需要的 ...