fork(), read(), write(), O_APPEND 使用

文件描述符和FILE*区别(open,write,read),重定向(dup2) 做调用库函数fopen()返回的指针类型。操作系统为了管理文件,定义了一个数据结构file来管理文件。而库函数参与了封装,封装成FILE,直接与FILE*打交道。file!= FILEstruct FILE 内部包含。 阅读详情

互应Lab03 fork(), read(), write(), O_APPEND 练习

运行示例程序

fork1.c

linux中fork()函数详解 - 学习记录园 - 博客园

fork调用仅被调用一次,能返回两次,可有三种返回值:
1)在父进程中,fork返回新创建子进程的进程ID;
2)在子进程中,fork返回0;
3)如果出现错误,fork返回一个负值;

创建新进程成功后,系统中出现两个基本完全相同的进程,这两个进程执行没有固定的先后顺序,哪个进程先执行要看系统的进程调度策略。

两个进程的变量都是独立的,存在不同的地址中,不是共用的,这点要注意。

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main(void){
    pid_t t;
    // fork is going to create a child process
    t=fork();
    printf("fork returned %d\n",t);
    // exit is to terminate a process and release all the resources
    exit(0);
}

在这里插入图片描述

fork2.c
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>


int main(void){

    pid_t t;

    printf("Original proram, pid = %d\n",getpid());
    t = fork();

    if(t==0){
        printf("In child process, pid = %d, ppid=%d\n",getpid(),getppid());
    }
    else{
        printf("In parent, pid = %d, fork returned = %d\n",
                getpid(),t);
    }
}

结果:

kunling@kunling-VirtualBox:~/Internet_Application/lab03$ ./fork2.out 
Original proram, pid = 3921
In parent, pid = 3921, ppid=3893, fork returned = 3922
kunling@kunling-VirtualBox:~/Internet_Application/lab03$ In child process, pid = 3922, ppid=1110
kunling@kunling-VirtualBox:~/Internet_Application/lab03$ gcc fork2.c -o fork2.out
kunling@kunling-VirtualBox:~/Internet_Application/lab03$ ./fork2.out 
Original proram, pid = 4041
In parent, pid = 4041, fork returned = 4042
kunling@kunling-VirtualBox:~/Internet_Application/lab03$ In child process, pid = 4042, ppid=1110

发现:

在虚拟机上创建新的进程和理论上是不一样的。这个问题需要探讨,可能是因为虚拟机请求主系统创建,那个pid是主系统的?

感觉Ubuntu打开终端老是要搞路径很麻烦,下载nautilus-open-terminal。

ubuntu14设置在当前目录打开终端_xbcReal的博客-优快云博客

exec1.c
#include<unistd.h>
#include<stdio.h>

int main (void){
    char *arg[] = {"/bin/ls",0};
    /* fork, and exec within child process*/
    if(fork()==0){
        printf("In child process:\n");
        execv(arg[0],arg);
        printf("I will never be called\n");
    }
    printf("Execution continues in parent process\n");
}

输出结果:

kunling@kunling-VirtualBox:~/Internet_Application/lab03$ ./exec1.out 
Execution continues in parent process

kunling@kunling-VirtualBox:~/Internet_Application/lab03$ In child process:
exec1.c   exec1.out  fork1.out    fork2.c~
exec1.c~  fork1.c    fork2.c    fork2.out
lseek1.c
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h> //exit()

char buf1[] ="abcdefghij";
char buf2[]="ABCDEFGHIJ";
#define FILE_MODE 0644


int main (void){
    int fd;

    if((fd = creat("file.hole",FILE_MODE))<0)
    {
        printf("creat error\n");

        exit(1);
    }
    if(write(fd,buf1,10)!=10){
        printf("buf1 write error\n");
        exit(1);
    }
    /*offset now = 10*/
    if(lseek(fd,40,SEEK_SET)==-1){
    printf("lseek error\n");
    exit(1);
    }
    /*offset now = 40*/
    if(write(fd,buf2,10)!=10){
    printf("buf2 write error\n");
    exit(1);
    }
    /*offset now = 50*/
    exit(0);
}

输出结果:

kunling@kunling-VirtualBox:~/Internet_Application/lab03$ od -c file.hole 
0000000   a   b   c   d   e   f   g   h   i   j  \0  \0  \0  \0  \0  \0
0000020  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
0000040  \0  \0  \0  \0  \0  \0  \0  \0   A   B   C   D   E   F   G   H
0000060   I   J
0000062
readwrite1.c
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

int main(void){
        char quit='.';
        char buf[10];
        int fd;
        if((fd=open("out.out", O_RDWR| O_CREAT))==-1)
        printf("Error in opening\n");

        while(buf[0]!= quit) //遇到‘.'就结束!
        {
             read(0 ,buf, 1);
            write(fd,buf, 1);
            write(1 ,buf, 1);

        }
        close(fd);
}

输出结果:

root@kunling-VirtualBox:/home/kunling/Internet_Application/lab03# ./readwrite1.out 
1234567890
1234567890
qwertyuio
qwertyuio
ff.
ff.root@kunling-VirtualBox:/home/kunling/Internet_Application/lab03# 
root@kunling-VirtualBox:/home/kunling/Internet_Application/lab03# od -c out.out 0000000   1   2   3   4   5   6   7   8   9   0  \n   q   w   e   r   t
0000020   y   u   i   o  \n   f   f   .
0000030

验收O_APPEND的特性

lseek的与O_APPEND的冲突_大海蓝天的专栏-优快云博客

  • 读取特性

    按照lseek文件指针读取

#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h> 

int main(){
    char rbuf1[100];
    int fd;
    int size;
    int currpos;

    //在当前目录创建或者打开文件
    fd = open("testing.txt",O_RDWR| O_APPEND);
    if(fd<0)
        printf("open failed");
    //移动文件指针到开头
    currpos = lseek(fd, 0 , SEEK_SET);

    if(currpos!=0){
    printf("lseek error");
    return -1;
    }

    if(read(fd,rbuf1,sizeof(rbuf1))<0)
    printf("read error!");

    //打印读取到的文件内容
    printf("%s",rbuf1);
    close(fd);
    return 0;
}
  • 写入特性

    lseek文件指针失效,在文件末尾附加。

#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
#include <stdlib.h>

int main(){
    char str_write1[] = "999";
    char str_write2[] = "000";
    char rbuf1[100];
    char rbuf2[100];
    int fd;
    int size;    
       int currpos;

    //在当前目录创建或者打开文件
    fd = open("testing.txt",O_RDWR|O_APPEND|O_CREAT, 0644);
        if(fd<0){
        printf("open and creat failed");
    }

    //移动文件指针到开头
    currpos = lseek(fd, 0 , SEEK_SET);
    if(currpos!=0){
    printf("lseek error");
    return -1;
    }

    //打印当前文件指针位置
    printf("file pointer position: %d\n",currpos);

    //向文件中写入
    size = write(fd, "999", strlen("999"));
    close(fd);
    return 0;
}

动文件指针到开头
currpos = lseek(fd, 0 , SEEK_SET);
if(currpos!=0){
printf(“lseek error”);
return -1;
}

//打印当前文件指针位置
printf("file pointer position: %d\n",currpos);

//向文件中写入
size = write(fd, "999", strlen("999"));
close(fd);
return 0;

}

Linux文件I/O机制与性能优化实践 文件I/O是操作系统核心功能之一,Linux通过'一切皆文件'的哲学统一了各类资源的访问接口。底层机制上,内核通过文件描述符、页缓存和系统调用实现高效I/O操作。在性能优化方面,Linux提供了页缓存预读、直接I/O和异步I/O等多种技术,其中io_uring作为新一代异步I/O框架,显著提升了高并发场景下的吞吐量。这些技术在数据库系统、网络服务和云计算等场景中都有广泛应用。理解文件描述符管理、同步机制和重定向原理,对于开发高性能Linux应用至关重要,特别是在需要处理大量文件操作或实现进程通信的场景中。 阅读详情

相关推荐

O_APPEND与读操作

当以O_APPEND选项打开一个文件时,验证能否使用lseek修改文件偏移量。若能修改,那修改之后,读操作是从文件尾部读,还是从修改后的偏移量开始读,编程进行验证

linux基础——fork()和文件操作

Linux代码中主函数的参数 //参数个数 argc(至少有一个) //参数内容 argv(文件名就是其中一个) //环境变量 envp int main(int argc,char *argv[],char *envp[]){ printf("argc=%d\n",argc);//打印函数个数 int i = 0; for(;i<argc;i++){ printf("argv[%d]=%s\n",i,argv[i]);//打印函数内容 } for(i = 0;envp[i] !=

weixin_45725491的博客 477

MT6816角度传感器SPI通信避坑指南:从数据手册到稳定读取的3个关键步骤

本文详细解析了MT6816角度传感器SPI通信中的常见问题与解决方案,包括寄存器地址计算、SPI时序配置和数据校验等关键步骤。通过实测波形和代码示例,帮助工程师避开数据手册中的隐藏陷阱,实现稳定可靠的角度数据读取,特别适用于高精度电机控制场景。

weixin_42520573的博客 517

Linux下进程控制编程(父进程写入数据,子进程读出数据)

//父进程 write 子进程 read //需要用到的函数 open,write,memset(清空缓存buf),read,fork(创建子进程),sleep, #include &lt;stdio.h&gt; #include &lt;sys/types.h&gt; #include &lt;sys/stat.h&gt; #include &lt;fcntl.h&gt; #in...

Y先生的自留地 3971

STM32F407通过SMBus协议精准读取BQ40Z50电池电量

本文详细介绍了STM32F407通过SMBus协议精准读取BQ40Z50电池电量的实现方法。从硬件连接到软件驱动开发,再到通信异常排查,提供了完整的解决方案。重点解析了SMBus协议的特殊时序要求、GPIO模拟驱动的关键代码,以及实际调试中的常见问题与对策,帮助开发者高效完成电池管理系统开发。

weixin_29189003的博客 253

DIY音频必备:手把手教你用AB类功放模块打造高保真桌面音响(含电路图)

本文详细指导如何利用AB类功放模块DIY高保真桌面音响,涵盖选型指南、核心元器件清单、电路搭建与焊接工艺,以及系统调试与音质优化技巧。AB类功放以其接近A类功放的音质和B类功放的效率,成为音频爱好者的理想选择,适合有一定电子基础的实践者。

weixin_42665725的博客 445

fork

获取当前进程的PID和父进程的PID。 创建getpid1.c,编辑如下内容 执行过程: 在当前系统中使用ps和grep查找父进程2330,可以看到,id为2330的进程为bash即当前的脚本程序,因为是在当前bash中运行此程序,所以父进程为bash 进程创建fork() 产生进程的方式比较多,fork()是其中的一种方式。fork()函数以父进程为蓝本复制一个进程,其ID号和父进程ID号...

weixin_45413479的博客 327

GStreamer —— 2.1、Windows搭建GStreamer环境,Qt加载GStreamer库后运行 - “教程1:Hello world!“(附:完整源码)

GStreamer —— 2、Windows搭建GStreamer环境,Qt加载GStreamer库后运行"教程1:Hello world!"

797

4、fork()复制进程

1、fork复制进程 进程: 2、父进程子进程 stu@stu-virtual-machine:~/Test/Forkex$ vi fork1.c stu@stu-virtual-machine:~/Test/Forkex$ gcc -o fork1 fork1.c stu@stu-virtual-machine:~/Test/Forkex$ ./fork1 s=parent,ppid=4067,pid=4390 s=child,ppid=4390,pid=4391 s=parent,ppid=4067

m0_57519884的博客 175

1.2 amdgpu_bo的设计分析 — gem层和ttm层

本文分析了AMD KFD的BO设计架构,重点介绍了DRM子系统中缓冲对象的多层继承关系。文章首先展示了核心继承层次图,包括DRM通用层(drm_gem_object)、TTM内存管理层(ttm_buffer_object)、AMD驱动层(amdgpu_bo)和KFD计算层(kgd_mem)。随后详细解析了drm_gem_object结构体的关键功能,包括用户空间接口管理、内存映射支持、引用计数机制以及DMA-BUF导入/导出功能。

图形/计算GPU的驱动与虚拟化技术分享园地 2549

深入大模型-13-大模型Skills应用之标准目录结构和开发一个Skill的步骤

首先对比Prompt工程,上下文工程,Skills工程,MCP工具的概念与区别,然后介绍Skill的标准目录结构,同时描述了开发一个Skill的步骤和最佳实践。

qq_20466211的博客 748

fork()函数与vfork()函数总结

首先介绍下fork函数 #include <sys/types.h> #include <unistd.h> pid_t fork (void ); 正确返回: 父进程中返回子进程的进程号;子进程中返回 0;(单调用双返回函数) 错误返回:-1; 子进程是父进程的一个拷贝。具体说, 子进程从父进程那得到了数据段和堆栈段,但不是与父进程共享而是单独分配内存。fork...

不甘平凡的码农 1159

基于深度确定性策略梯度的永磁同步电机强化学习控制方法

本文提出了一种基于深度确定性策略梯度(DDPG)的永磁同步电机(PMSM)电流内环智能控制方法。首先建立了PMSM在d-q坐标系下的数学模型,分析了传统矢量控制双闭环系统中PI控制器的局限性。针对电流内环控制问题,设计了包含电流跟踪误差、转速信息和历史控制量的状态空间,将电压输出作为动作空间,并构建了兼顾跟踪精度和响应速度的奖励函数。通过DDPG算法训练智能体,使其能够自适应调整控制策略。仿真结果表明,与固定参数的PI控制器相比,DDPG控制器在动态响应速度和抗干扰能力方面具有明显优势,为PMSM高性能控制

huanghm88的专栏 104

Linux的I/O系统调用函数之read,open,write

** (一)open ** 进程是通过调用open函数来打开一个已存在的文件或者创建一个新文件的。 int open(char *filename,int flags,mode_t mode); open函数将filename转换为一个文件描述符,并且返回描述符数字。返回的描述符总是在进程中当前没有打开的最小描述符。 1.flags参数指明了进程打算如何访问这个文件: O_RDONLY 只...

z1911725145的博客 707

C#跨平台制图新纪元:Mapsui,一库在手,地图我有

深入学习Mapsui的渲染机制,定制属于你的地图样式,无论是颜色、图标还是文字,都可以随心所欲。

java专栏 1458

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

文件描述符,Linux操作系统文件的系统调用 open read write close

fork——父进程打开的文件fork复制到子进程中,子进程也可以访问。 c 语言使用 fopen(),打开一个文件,文件类型为 FILE* fclose()关闭文件。 Linux通过操作系统的子模块——文件系统来管理文件 通过文件id号来管理文件,每个文件的ID号是唯一的 一、 open c语言中使用fopen打开文件,fopen是库函数。 Linux 通过open打开文件,是一种系统调用,在内核中实现。 fopen->open(),fopen底层调用open 包含头文件#inc

swint_er的博客 1592

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Linux的系统调用open,write,read,close,及相关总结

在进行C语言学习的时候我们了解到了C语言相关的一些IO操作,如fopen,fwrite,fread,fprintf,fclose等相关函数,他们都是由C库函数提供的一些函数,是将操作系统的系统调用加以封装,虽说Linux是由C语言实现的,但为了使我们更加的了解Linux,就需要了解更接近与底层的一些IO操作,因此就需要来了解下基本的系统调用—open,write,read,close 首先我们来...

erwuhuoche的博客 1211

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

从实例中学习系统I/O(入门级)

I/O即输入/输出,此日志只讨论Unix I/O 基础知识 一切皆文件。所有的I/O设备都被模型化为文件,则所有输入/输出都被当作对相应文件的读和写来执行。 描述符。打开文件时内核会返回一个小的非负整数,叫做描述符,它在后续对此文件的所有操作中标识这个文件。 Linux shell 创建的每个进程开始时都有三个打开的文件: 标准输入(描述符为0)、标准输出(描述符为1)、标准错误(描述符为2)。...

T_selenita的博客 281

【Linux】基础 I/O 深度解析:FILE、文件描述符、open/read/write、重定向与缓冲区

学习 Linux I/O 时,最容易产生的错觉是:这些接口只是“不同写法”。printf()fwrite()属于 C 标准库,操作的是FILE *,通常带有用户态缓冲;write()是系统调用接口,操作的是整数文件描述符fd;fd再通过进程的文件描述符表引用内核中的打开文件对象;内核最终可能把请求交给文件系统、管道、终端驱动或网络协议栈。为什么printf()后文件里暂时没有内容,而write()的表现不同?为什么关闭 fd 1 后再open(),新文件常常恰好拿到 fd 1?

星光编译者的技术博客,专注 C/C++、Linux、数据结构与算法。 649

csapp之系统级i/o

一、UNIX I/O 在UNIX系统中有一个说法,一切皆文件。所有的I/O设备,如网络、磁盘都被模型化为文件,而所有的输入和输出都被当做对相应文件的读和写来执行。这种将设备映射为文件的方式,允许UNIX内核引出一个简单、低级的应用接口,称为UNIX I/O,这使得所有的输入和输出都能以一种统一且一致的方式来执行。 即 1.打开文件 内核返回一个小的非负整数,叫做描述符 等于内核分配一个文件名,来标...

weixin_44027734的博客 262

系统级I/O中的共享文件

对于操作系统而言,I/O操作可以分为两类,一类是带缓存的IO,又称为标准IO(C标准库中提供了标准IO库,即stdio),它实现了跨平台的用户缓存解决方案。另一类是Unix/Linux下的文件IO,又称直接IO,即文件访问机制不经过操作系统内核的缓存,数据直接在磁盘和应用程序地址空间进行传输。 ...

qq_45610525的博客 233

深入理解Linux文件I/O:文件描述符与系统调用

文件I/O是操作系统与存储设备交互的核心机制,涉及文件描述符、系统调用等基础概念。文件描述符作为Unix/Linux系统中的抽象句柄,通过非负整数唯一标识打开的文件。系统调用如open()、read()、write()等实现了用户程序与内核的交互,完成文件操作。重定向技术则改变了标准输入/输出流的默认行为,广泛应用于shell脚本和进程通信。理解这些机制对于开发高性能应用、处理并发I/O以及优化系统资源至关重要。通过掌握文件描述符的生命周期管理、重定向原理以及高级I/O技术如分散/聚集I/O,开发者能够构建

weixin_33806300的博客 548

【Linux-Day7-文件操作,fork与malloc结合】

(1)c 语言中文件操作回顾C语言操作文件分为三步1)打开文件2)读写文件3)关闭文件。有FILEfilename: 文件名,包括路径,如果不显式含有路径,则表示当前路径。mode:文件打开模式,指出对该文件可进行的操作。常见的打开模式如 “r” 表示只读, “w” 表示只写,“rw” 表示读写,“a” 表示追加写入。返回值: 打开成功,返回该文件对应的 FILE 类型的指针;打开失败,返回 NULL。故需定义 FILE 类型的指针变量,保存该函数的返回值。​。

qq_63282188的博客 260

解析输出缓冲区与fork交互导致的日志丢失问题

标准I/O缓冲区是提升程序I/O效率的关键机制,通过减少系统调用次数来优化性能。其工作原理涉及全缓冲、行缓冲和无缓冲三种策略,分别对应不同的数据刷新条件。在多进程编程中,fork系统调用采用写时复制技术复制父进程内存空间,这会导致输出缓冲区的内容也被复制到子进程。当父子进程未正确处理缓冲区时,就会出现日志丢失或重复写入等问题。这种机制尤其影响守护进程、任务调度系统等需要多进程协作的场景。理解缓冲区与fork的交互原理,可以帮助开发者避免常见的进程间通信陷阱,确保关键日志的完整性。通过合理设置缓冲模式或使用原

weixin_33912453的博客 349

系统级I/O入门

一切皆文件。 (本篇中的例子若非特殊说明,使用的都是abcde.txt,文件内容就是abdce) Linux shell创建的每个进程开始时都有三个打开的文件(在头文件<unisted.h>中定义): 0:标准输入 1:标准输出 2:标准错误 文件操作有:open,read,write,stat,dup2,close,lseek; 每个Linux文件都有一个类型:普通文件,目录,套接...

weixin_43329358的博客 241

Linux——fork与文件操作

Linux 下与文件操作有关的函数都属于系统调用,包括 open、read、write 和 close 函数,可以通过命令 man 2 open 的方式查看函数的声明。

Singularitys123的博客 789
上一篇: windows 脚本bat中调用bat
下一篇: AM信号的调制与解调
groundnut888
博客等级 码龄6年 59粉丝 27原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值