Linux文件操作应用及open和fork

news2024/11/24 18:41:50

1.文件操作的应用:

1).打开一个文件并往里面写入hello:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <assert.h>
int main()
{
    int fd=open("file.txt",O_WRONLY|O_CREAT,0600);
    assert(fd!=-1);

    printf("fd=%d\n",fd);
    write(fd,"hello",5);

    close(fd);
    exit(0);
}

2).打开文件,读取文件内容;

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <stdlib.h>
int main()
{
    int fd=open("file.txt",O_RDONLY);
    assert(fd!=-1);

    char buff[128]={0};
    int n=read(fd,buff,127);
    printf("n=%d,buff=%s\n",n,buff);

    close(fd);

    exit(0);
}

3).利用读和写对文件进行复制

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

int main()
{
    int fdr=open("file.txt",O_RDONLY);
    int fdw=open("newfile.txt",O_WRONLY|O_CREAT,0600);

    if(fdr==-1||fdw==-1)
    {
        exit(0);
    }

    char buff[256]={0};
    int num=0;

    while((num=read(fdr,buff,256))>0)
    {
        write(fdw,buff,num);
    }
    close(fdr);
    close(fdw);

    exit(0);
}

4).实现类似cp 命令

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

int main(int argc,char *argv[])
{
    if(argc!=3)
    {
        printf("argc error\n");
    }
    char *file_name=argv[1];
    char *newfile_name=argv[2];

    int fdr=open(file_name,O_RDONLY);
    int fdw=open(newfile_name,O_WRONLY|O_CREAT,0600);

    if(fdr==-1||fdw==-1)
    {
        exit(0);
    }

    char buff[256]={0};
    int num=0;

    while((num=read(fdr,buff,256))>0)
    {
        write(fdw,buff,num);
    }
    close(fdr);
    close(fdw);

    exit(0);
}

2.面试题详解fork

面试题目1:

(1)fork 以后,父进程打开的文件指针位置在子进程里面是否一样?(先open再fork)
(2)能否用代码简单的验证一下?
(3)先fork再打开文件父子进程是否共享偏移量?父进程打开的文件指针位置在子进程里面是否一样?能否用代码简单验证一下.(先fork再open会怎么样?)

inode:

文件数据都储存在”块”中,那么很显然,我们还必须找到一个地方储存文件的元信息,比如文件的创建者、文件的创建日期、文件的大小等等。这种储存文件元信息的区域就叫做inode,中文译名为”索引节点”。

每一个文件都有对应的inode,里面包含了与该文件有关的一些信息。通过这个inode节点,即通过文件具体的一些信息,我们才能找到这个文件,读取它.

每个inode都有一个号码,操作系统用inode号码来识别不同的文件。

2).先打开再fork的流程(重点)  

代码如下:

先创建一个文件file.txt,内容为abcdefg;

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

int main()
{
    int fd=open("file.txt",O_RDONLY);
    assert(fd!=-1);

    pid_t pid=fork();
    assert(pid!=-1);

    if(pid==0)
    {
        char buff[128]={0};
        int n=read(fd,buff,1);
        printf("child:%s\n",buff);
        sleep(1);
        n=read(fd,buff,1);
        printf("child:%s\n",buff);
    }
    else
    {
        char buff[128]={0};
        int n=read(fd,buff,1);
        printf("parent:%s\n",buff);
        sleep(1);
        n=read(fd,buff,1);
        printf("parent:%s\n",buff);

    }

    close(fd);
    exit(0);
}

父进程打开文件以后,fork产生子进程,父子进程共享打开的文件,同时共享文件偏移量;

为什么?如图:

3).先fork再open

代码修改如下:

 pid_t pid=fork();
  assert(pid!=-1);

int fd=open("file.txt",O_RDONLY);
    assert(fd!=-1);

(了解文件偏移量不共享)

为什么?如图:

面试题答案:

在 (1)fork 之前打开的文件,在复制进程后,父子进程共享文件偏移量,所以文件指针在相同位置。(2)代码详见课件(3)先fork再打开文件,父子进程各自打开各自的,不共享偏移量;

面试题目2:

4).系统调用与库函数的区别

比如自己写的函数,调用的时候就是调换到函数的入口地址一句一句执行,但是系统调用就不一样,系统调用一旦执行,我们就需要 从用户空间切换到内核空间.
比如fopen :库函数 open:系统调用 fork:系统调用
可以man fopen (显示3),man  2 open (显示2),man  fork (显示2)

系统调用的执行过程:

在Linux中,每个系统调用都被赋予了一个系统调用号.这样,通过这个独一无二的号就可以关联系统调用.当用户空间的进程执行一个系统调用的时候,这个系统调用号就用来指明到底是要执行哪个系统调用号;进程并不会提及系统调用的名称;

系统调用是为了方便使用操作系统的接口,而库函数则是为了人们编程的方便;
库函数调用与系统无关,不同的系统,调用库函数,库函数会调用不同的底层函数实现,因此可移植性好;

5).malloc和free的三个问题:

思考下面三个问题:

(1)申请了一块空间没有free,进程就结束了,那么空间被回收了吗?
(2)malloc()申请3G的内存能否成功?判断依据是什么?

(3)父进程堆区申请的空间复制后,子进程也会有一份,也需要释放?

演示代码:

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

int main()
{
    char *s=(char *)malloc(1024ll*1024*1024*3);
    assert(s!=NULL);
    memset(s,0,1024ll*1024*1024*3);
    printf("main over!\n");
    exit(0);
}

1.进程在执行的过程中,malloc申请空间,不使用时,没有free就会出现内存泄漏;
如果进程结束了,那么所有向操作系统申请的内存都会被回放(释放);

2.申请1G或者更大空间,到底能不能成功?
如果当前的物理内存剩余空间够用,那么申请的空间肯定能成功;

如果不够用,我们先要看有没有虚拟内存,如果没有,不能成功;如果有虚拟内存,那么我们看内存+虚拟空间的大小能否满足,如果满足,那么我们是可以申请成功的,如果不够,当然不能成功;

首先我们需要了解一个名词:虚拟内存:

基于分页技术或者分页和分段技术的组合的虚拟内存,是现代计算机中内存管理最常用的方法之一.虚拟内存对应用程序完全透明,使得每个进程在执行时好像有无限的内存可用.为实现这一点,操作系统为每个进程在磁盘上创建一块虚拟地址空间,即虚拟内存.在需要的时候可以把部分虚拟内存载入到正在的内存中.这样,多个进程便可以共享相对比较小的内存.为了使虚拟内存载入到真正的内存中.这样,多个进程便可以共享相对比较小的内存.为了使虚拟内存更为有效,需要硬件机制来执行基本的分页和分段功能,如虚拟地址和实地址之间的地址转换.

虚拟内存提供的三个重要的能力:
1) 它将主存看成是一个存储在磁盘上的地址空间的高速缓存,在主存中只保存活动区域,根据需要在磁盘和主存之间来回传送数据,使得能够运行比内存大的多的进程。
2) 它为每个进程提供了一致的地址空间,从而简化了存储器管理.
3) 它保护每个进程的地址空间不被其他进程破坏 .

了解两个命令:
sudo swapoff -a;关闭虚拟内存;
sudo swapon -a;开启虚拟内存;

(3)(3)父进程堆区申请的空间复制后,子进程是不是也会有一份?是不是也需要释放?

我们先来看下面的代码:

#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
    char *s=(char *)malloc(128);
    assert(s!=NULL);

    pid_t pid=fork();
    assert(pid!=-1);

    free(s);

    exit(0);
}

编译运行并没有出错,如果是共享空间的话, 那么父子进程会对一个空间分别free,我们有前面学过的C语言可以知道,如果我们对一个空间free两次,编译运行会出现错误.

所以父子进程堆空间不共享(这里指的是每个进程的堆空间).哪怕父子进程对申请的对空间都没有操作.

其实如果对空间操作也是没有问题的,如下:

#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>  //1
int main()
{
    char *s=(char *)malloc(128);
    assert(s!=NULL);

    pid_t pid=fork();
    assert(pid!=-1);

    if(pid==0)//2
    {
        strcpy(s,"child");//3
    }
    else  //4
    {
        strcpy(s,"parent");//5
    }
    printf("s=%s\n",s); //6
    free(s);

    exit(0);
}

结论:

父进程堆区申请的空间复制后,子进程也有一份.也需要释放;也就是说,fork会把进程的上下文都复制一遍,如果是malloc申请的话,内核会给子进程分配和父进程一样多的空间,父子进程都需要分别free;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1260691.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

oracle免费资源 终止实例 以及新建一台实例的折腾记录

事情的背景是这样的&#xff0c;我的一台oracle小鸡&#xff0c;不太好用的样子&#xff0c;有时候SSH连不上&#xff0c;有时候莫名其妙卡住。所以我就想把它重新安装一下系统&#xff0c;恢复成最初的样子。 然后在网上查资料&#xff0c;是有办法把系统重装一下的。但是略微…

pdf加密文件解密(pdf文件解密小工具)

工具放在文章末尾&#xff01; 1.pdf文件加密后会有很多使用权限的限制很不方便&#xff0c;只要是为了pdf的数据不被二次利用&#xff0c;未加密的pdf功能都是可以正常使用的 2.加密后的pdf使用权限会被限制部分 3.工具只能解决pdf编辑等加密情况&#xff0c;不能解决文件打…

深度学习及其基本原理

深度学习的 Ups and Downs概念区分神经网络的构成深度学习基本原理深度学习的普遍近似定理扩展&#xff1a;反卷积网络——可视化每一层提取的特征 深度学习的 Ups and Downs 1958&#xff1a;感知机&#xff08;线性模型&#xff09;1969&#xff1a;感知机有局限性1980s&…

stream流和方法引用

1.Stream流 1.1体验Stream流【理解】 案例需求 按照下面的要求完成集合的创建和遍历 创建一个集合&#xff0c;存储多个字符串元素把集合中所有以"张"开头的元素存储到一个新的集合把"张"开头的集合中的长度为3的元素存储到一个新的集合遍历上一步得到的集…

Go 基本语法

一、​​​​变量定义方法 var 定义变量 var 变量名 类型 表达式 var name string "Snail" var age int 21 var isOK bool bool 2.类型推导方式定义变量 a 在函数内部&#xff0c;可以使用更简略的: 方式声明并初始化变量**注意&#xff1a;**短变量只能用于声…

MySQL数据库如何实现跨服务器访问数据

点击上方蓝字关注我 在使用MySQL数据库时&#xff0c;很多同学经常会问&#xff0c;我能跨服务器访问另一库的数据么&#xff1f;得到的答案很多时候是让人失望的。那么如果真的需要访问&#xff0c;又不想使用拷贝表及数据的方式&#xff0c;可以实现么&#xff0c;又该如何实…

【jupyter notebook中插件 nbextensions 安装失败分析与解决方法】

文章目录 问题描述分析与解决总结 问题描述 一开始在安装 notebook 中的插件 nbextensions 时根本没有注意到版本的适配问题&#xff0c;都是进行默认的安装&#xff0c;结果安装是最新版本的 notebook7.x&#xff0c;恰好 notebook7.x 版本不再适应插件 nbextensions&#xf…

【计算方法与科学建模】矩阵特征值与特征向量的计算(五):乘幂法的加速(带有原点移位的乘幂法)

文章目录 一、Jacobi 旋转法二、Jacobi 过关法三、Householder 方法四、乘幂法四、乘幂法的加速 矩阵的特征值&#xff08;eigenvalue&#xff09;和特征向量&#xff08;eigenvector&#xff09;在很多应用中都具有重要的数学和物理意义。 本文将详细介绍乘幂法的基本原理和步…

尚硅谷大数据项目《在线教育之实时数仓》笔记008

视频地址&#xff1a;尚硅谷大数据项目《在线教育之实时数仓》_哔哩哔哩_bilibili 目录 第10章 数仓开发之DWS层 P066 P067 P068 P069 P070 P071 P072 P073 P074 P075 P076 P077 P078 P079 P080 P081 P082 第10章 数仓开发之DWS层 P066 第10章 数仓开发之DW…

互联网金融智能风险防控技术要求

《互联网金融智能风险防控技术要求》 8月6日&#xff0c;国家市场监督管理总局和国家标准化管理委员会发布《互联网金融智能风险防控技术要求》&#xff08;GB/T 42929-2023&#xff09;&#xff08;以下简称“《要求》”&#xff09;&#xff0c;将于2023年12月1日实施。 《要…

MySQL数据库:外键、唯一键、唯一索引

目录 说明 一、如果要使用外键&#xff0c;表的存储引擎选择哪个&#xff1f; 1.1 答 1.2 示范 1.2.1 主表 &#xff08;1&#xff09;MyISAM的表&#xff1a;masterTable2 &#xff08;2&#xff09;InnoDB的表&#xff1a;masterTable1 1.2.2 从表 &#xff08;1&am…

图书管理系统源码,图书管理系统开发,图书借阅系统源码四TuShuManager应用程序MVC视图View

Asp.net web应用程序MVC之View视图 .ASP.NET MVC页面也就是要说的视图基本被放在Views文件夹下&#xff1b; 2.利用APS.NET MVC模板生成框架&#xff0c;Views文件夹下的默认页面为.cshtml页面&#xff1b; 3.ASP.NET MVC默认页面为Razor格式的页面&#xff0c;因此默认页面为.…

无人机光伏巡检代替人工,贵州电站运维升级

无人机光伏巡检如何做到降本增效&#xff1f;贵州省光伏电站有新招&#xff01;某70MWp的光伏电站通过引入复亚智能无人机光伏巡检系统&#xff0c;专注于使用无人机对区域内的光伏面板进行自动巡航巡查&#xff0c;利用自动化巡检和故障识别技术&#xff0c;显著提升了光伏电站…

UniPro集成华为云WeLink 为企业客户构建互为联接的协作平台

华为云WeLink是华为开启数字化办公体验、帮助企业实现数字化转型的实践&#xff0c;类似钉钉。UniPro的客户企业中&#xff0c;有使用WeLink作为协作工具的&#xff0c;基于客户的实际业务需求&#xff0c;UniPro实现了与WeLink集成的能力&#xff0c;以帮助客户企业丰富和扩展…

【触想智能】无风扇工控电脑一体机使用优势分析

无风扇工控电脑一体机是属于工控一体机分类中的其中一种&#xff0c;看名字&#xff0c;很明显就是没有散热风扇的工控电脑一体机&#xff0c;而平常我们使用的电脑主机是带有电源风扇、CPU散热风扇的。 无风扇工控电脑一体机的配置组成和商用电脑主机的配置基本一样&#xff0…

【读懂AUTOSAR】DoIP模块(1)-- 使用场景和链接的建立规范

引子 --什么是?为什么使用DoIP? DoIP就是通过IP进行诊断的意思(Diagnostic Over IP)。我们熟悉的诊断都是通过CAN总线的啊,为什么要通过IP?IP是什么? IP就是Internet Protocol,就是”互联网协议“啦! 那DoIP就是通过互联网进行的诊断喽,也可以叫做“基于以太网的诊…

JMeter之压力测试——混合场景并发

在实际的压力测试场景中&#xff0c;有时会遇到多个场景混合并发的情况&#xff0c;这时就需要设置不同的并发比例对不同场景请求数量的控制&#xff0c;下面提供两种方案。 一、多线程组方案 1.业务场景设计如下&#xff1a;场景A、场景B、场景C&#xff0c;三个场景按照并发…

FPGA模块——AD高速转换模块(并行输出转换的数据)

FPGA模块——AD高速转换模块&#xff08;并行输出转换的数据&#xff09; &#xff08;1&#xff09;AD9280/3PA9280芯片&#xff08;2&#xff09;代码 &#xff08;1&#xff09;AD9280/3PA9280芯片 AD9280/3PA9280芯片的引脚功能&#xff1a; 工作电压2.7到5.5v 数据对应&a…

<Linux> 文件理解与操作

目录 前言&#xff1a; 一、关于文件的预备知识 二、C语言文件操作 1. fope 2. fclose 3. 文件写入 3.1 fprintf 3.2 snprintf 三、系统文件操作 1. open 2. close 3. write 4. read 四、C文件接口与系统文件IO的关系 五、文件描述符 1. 理解文件描述符 2. 文…

商用车自动驾驶政策现状及趋势预判

一、我国自动驾驶法规政策体系 二、重点领域法规政策进展 1、战略引导 2、法律法规 3、标准体系 4、测试认证 5、创新支持 6、配套环境 三、“十四五”期间政策发展趋势 1、应用场景 2、法规标准趋势