我的关联博文:

系统编程-进程-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. Pandas库学习笔记(1)

    参考:菜鸟教程 pandas库使用了NumPy的大多数功能.建议您先阅读有关NumPy的教程,然后再继续本教程. Pandas 适用于处理以下类型的数据: 与 SQL 或 Excel 表类似的,含异构 ...

  2. PixiJS源码分析系列:第三章 使用 canvas 作为渲染器

    使用 canvasRenderer 渲染 上一章分析了一下 Sprite 在默认 webgl 渲染器上的渲染,这章让我们把目光聚集到 canvasRenderer 上 使用 canvas 渲染器渲染图 ...

  3. APK包的加固手段收集(浅)

    目录 防止APK被调试 加壳 代码混淆: 检测调试器: 使用反调试技术: 环境检测: 使用Native代码: 多层防护: 防止APK被篡改 签名校验: V1 签名机制 V2 签名机制 V3 签名机制 ...

  4. Jmeter函数助手23-intSum

    intSum函数可用于计算两个或多个整数值的和. 要添加的第一个整数:必填,填入整数,不能为小数 要添加的第二个整数:必填,填入整数,不能为小数 存储结果的变量名(可选) 1. intSum函数求多个 ...

  5. Asp.Net Core之Identity源码学习

    什么是Identity ASP.NET Identity是构建核心 Web 应用程序(ASP.NET.登录和用户数据)的成员系统.ASP.NET核心标识允许您向应用程序添加登录功能,并可以轻松自定义有 ...

  6. windows11系统NVIDIA显卡驱动自动升级导致2070 Super显卡失效 —— 552.22版本自动升级到560.70版本后2070 Super型号显卡停止工作

    操作系统 Windows11,旧版本显卡驱动是552.22,由于安装的是NVIDIA Geforce Experience后显卡驱动自动升级到560.77版本,然后显卡不再工作. 重新安装显卡驱动56 ...

  7. AI大模型的技术之母 —— Attention Is All You Need —— Tansformer

    论文地址: https://arxiv.org/abs/1706.03762

  8. Leetcode: 586. Customer Placing the Largest Number of Orders

    题目要求如下: 给出的例子如下: 简单地说就是要找出表中订单最多客户的ID. 使用如下的代码进行实现: import pandas as pd def largest_orders(orders: p ...

  9. br4gOnB4ll靶机笔记

    br4gOnB4ll靶机笔记 这是一台vulnhub上的免费靶机,比较简单. 1.主机发现 主机发现 -sn 只做ping扫描,不做端口扫描 nmap -sn 192.168.84.1/24 Star ...

  10. 使用 onBeforeRouteLeave 组合式函数提升应用的用户体验

    title: 使用 onBeforeRouteLeave 组合式函数提升应用的用户体验 date: 2024/8/14 updated: 2024/8/14 author: cmdragon exce ...