转自:https://blog.csdn.net/qq_17019203/article/details/85051627

问题:open(2)函数打开文件是否将文件内容加载到内存空间

首先,文件打开后都会产生一个文件描述符fd,这个文件描述符其实是记录在PCB的文件描述符表中,而这个文件描述符实质上是一个结构体,用来存放跟打开文件相关的信息,基于此前提,我产生了两种假设

1、文件描述符结构体中只存储了文件在硬盘中的相应地址信息,并不将文件内容加载到内存中,这样做的好处是减少内存空间的占用,但大大增加了运行的时间(cpu存取内存数据的速度约ns级别,cpu存取硬盘数据的速度约为60000ns)。

2、文件描述符结构体为文件在内存中分配了地址空间来存放文件内容,这样做的好处是增加了运行速度,不足是当文件太大时严重占用内存空间。

3、如果问题2正确就产生了另一个问题,这块地址空间的大小和分配规则是什么?

接下来是我的探索过程和代码

第一步:我用open(2)函数打开了一个文件,设置连续读取文件,读取的间隔为3秒。

第二步:在读取的过程中我将还没被读取完的文件删除(另外打开一个bash,用rm命令删除)

#include

#include

#include

#include

#include

int main(int argc,char *argv[])

{

int fd;

char buf[128];

int read_size,write_size;

//open a file with read and write

fd = open(argv[1],O_RDWR);

if(fd == -1)

{

perror("open");

return 1;

}

while(1)

{

read_size = read(fd,buf,2);

if(read_size == 0) break;

write(1,buf,read_size);

sleep(3);

}

//close fd

close(fd);

return 0;

}

下面是运行结果:

bash 1

[sun@localhost file_func]$ ./a.out hello

#include

#include

int main(int argc,char *argv[])

{

int link_flag;

link_flag = link(argv[1],argv[2]);

if(link_flag == -1)

{

perror("link");

return 1;

}

if(link_flag == 0)

printf("creat hard link success...\n");

return 0;

}

bash 2

[sun@localhost file_func]$ rm hello

通过以上的结果我们能看出,在文件还没被读取完时将文件删除不会影响读取程序继续读取文件内容

结论1:用open(2)函数打开文件会将文件的内容加载到内存空间

接下来我们要探索的是,这个分配的地址空间大小上限是多少,文件类型的不同会不会产生不同的结果等问题

补充:

以上实验还存在一种可能性,就是rm 的原理和unlink是一样的(即rm是通过unlink封装的),等待程序运行完才会删除文件(阻塞删除),虽然删除文件操作是在文件执行完以后,但只要执行unlink文件马上就会消失看不到(在系统界面上消失,但在硬盘上还存在)

为了探索rm是不是通过unlink封装,我又进行了以下操作

一、创建虚拟映像使用rm命令

二、通过strace命令获取rm运行时产生的系统调用,命令如下

strace -f -F -o ./log.txt a.out

三、在系统调用里查找是否存在unlink函数

#include

#include

#include

#include

int main(void)

{

pid_t pid;

//creat child process

pid = fork();

if(pid == -1)

{

perror("fork");

return 1;

}

//child process

if(pid == 0)

{

//load a memory

int ex_flag=execlp("/bin/rm","rm","hello",NULL);

if(ex_flag == -1)

{

perror("execlp");

return 2;

}

return 0;

}

//father process

else

{

wait(NULL);

}

return 0;

}

通过strace产生的结果如下

mmap(0x3f02d8e000, 18600, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x3f02d8e000

13697 close(3) = 0

13697 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0665bb5000

13697 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0665bb4000

13697 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0665bb3000

13697 arch_prctl(ARCH_SET_FS, 0x7f0665bb4700) = 0

13697 mprotect(0x3f02d89000, 16384, PROT_READ) = 0

13697 mprotect(0x3f0241f000, 4096, PROT_READ) = 0

13697 munmap(0x7f0665bb6000, 51177) = 0

13697 brk(0) = 0x187b000

13697 brk(0x189c000) = 0x189c000

13697 open("/usr/lib/locale/locale-archive", O_RDONLY) = 3

13697 fstat(3, {st_mode=S_IFREG|0644, st_size=99158576, ...}) = 0

13697 mmap(NULL, 99158576, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f065fd22000

13697 close(3) = 0

13697 ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0

13697 newfstatat(AT_FDCWD, "hello", {st_mode=S_IFREG|0666, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0

13697 geteuid() = 500

13697 newfstatat(AT_FDCWD, "hello", {st_mode=S_IFREG|0666, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0

13697 faccessat(AT_FDCWD, "hello", W_OK) = 0

13697 unlinkat(AT_FDCWD, "hello", 0) = 0

13697 close(0) = 0

13697 close(1) = 0

13697 close(2) = 0

13697 exit_group(0) = ?

13696 <... wait4 resumed> NULL, 0, NULL) = 13697

13696 --- SIGCHLD (Child exited) @ 0 (0) ---

13696 exit_group(0) = ?

我们可以看到倒数第8行出现了一个unlinkat系统调用函数,根据unlinkat函数的定义,第三个参数取0时,unlinkat等价于unlink。

通过以上分析,我有以下结论:

1、open(2)函数在打开文件时,是否将文件内容加载到内存空间目前无法得知,在学习的时候老师的理论是linux在读取文件时候会将文件的地址内容加载到内存,而非文件的内容。

2、第一个实验结果主观上来看,因为在删除掉被读取文件后文件还能继续读取,所以open函数打开文件是将文件内容加载到内存空间的。

但通过客观分析,我们发现我们所认为的“rm删除文件,文件不在系统界面显示就是被删除了”这种想法是不对的,因为rm删除文件是调用了unlinkat系统函数,所以虽然在文件被读取时候我们看不到被读取文件在系统中显示,但此时文件还是存在于硬盘中的,只有当被读取文件被读取完成后才会真正的被删除。

————————————————

版权声明:本文为CSDN博主「虚渊玄」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qq_17019203/article/details/85051627

利用PHP的debug&lowbar;backtrace函数,实现PHP文件权限管理、动态加载

简述 可能大家都知道,php中有一个函数叫debug_backtrace,它可以回溯跟踪函数的调用信息,可以说是一个调试利器. 好,来复习一下 01 one(); 02 03 function one ...

(转)利用PHP的debug&lowbar;backtrace函数,实现PHP文件权限管理、动态加载 【反射】

linux 内存中建立文件,linux函数深入探索——open函数打开文件是否将文件内容加载到内存空间...相关推荐

  1. linux so lazyload,linux函数深入探索——open函数打开文件是否将文件内容加载到内存空间...

    转自:https://blog.csdn.net/qq_17019203/article/details/85051627 问题:open(2)函数打开文件是否将文件内容加载到内存空间 首先,文件打开 ...

  2. 把 mysql 整个加载进内存磁盘中_MySQL 缓冲池 是什么?

    Mysql 中数据是要落盘的,这点大家都知道.读写磁盘速度是很慢的,尤其和内存比起来更是没的说.但是,我们平时在执行 SQL 时,无论写操作还是读操作都能很快得到结果,并没有预想中的那么慢. 可能你会 ...

  3. Android加载图片内存溢出问题解决方法

    这篇文章主要介绍了Android加载图片内存溢出问题解决方法,本文讲解使用BitmapFactory.Options解决内存溢出问题,需要的朋友可以参考下 1. 在Android软件开发过程中,图片处 ...

  4. linux内核中启动页面,Linux内核启动过程分析

    下面给出内核映像完整的启动过程: arch/x86/boot/header.S: --->header第一部分(以前的bootsector.S):  载入bootloader到0x7c00处,设 ...

  5. Linux中mod相关的命令 内核模块化 mod相关命令都是用来动态加载内核模块/驱动程序模块...

    Linux中mod相关的命令 内核模块化   mod相关命令都是用来动态加载内核模块/驱动程序模块 http://baike.baidu.com/link?url=lxiKxFvYm-UfJIxMjz ...

  6. python变量区变量保存与加载_python – Flask:使用全局变量将数据文件加载到内存中...

    我有一个大的 XML文件,它被打开,加载到内存中,然后由 Python类关闭.简化示例如下所示: class Dictionary(): def __init__(self,filename): f ...

  7. mint linux更新内核,如何在Ubuntu/Linux Mint中安装最新Linux 5.2.5内核

    原标题:如何在Ubuntu/Linux Mint中安装最新Linux 5.2.5内核 Linux 5.2的Ubuntu主线内核包最终可以在32位和64位操作系统中下载和安装. 由于构建失败,Linux ...

  8. c语言文件 加载内存吗,把文件中的数据加载到内存进行查找C语言实现.docx

    把文件中的数据加载到内存进行查找C语言实现 #define _CRT_SECURE_NO_WARNINGS#include#include#includechar **pp=NULL;void ini ...

  9. java动态编译类文件并加载到内存中

    如果你想在动态编译并加载了class后,能够用hibernate的数据访问接口以面向对象的方式来操作该class类,请参考这篇博文-http://www.cnblogs.com/anai/p/4270 ...

最新文章

  1. xampp的Apache无法启动解决方法
  2. PAT甲级1073 Scientific Notation:[C++题解]字符串处理、科学计数法
  3. 为什么大家看到不错的文章更愿意收藏而不是点赞?
  4. Quantitative Researcher Summer Internship (for Overseas Schools)
  5. circRNA相互作用预测数据库CSCD2
  6. SpringSecurity OAuth2介绍
  7. Web服务器面临的五种应用层DOS威胁
  8. 光纤收发器的7大挑选技巧
  9. Class文件结构amp;字节码指令
  10. Error generating final archive: Debug Certificate expired on 的错误解决方法
  11. 多个不同版本的依赖maven怎样做出取舍
  12. Hive之架构 功能
  13. Oracle非重要文件恢复,redo、暂时文件、索引文件、password文件
  14. 用户数据销售额分析动态大屏看板+大屏数据可视化图表组件(折线图+圆柱图+散点图+饼图+漏斗图+雷达图+水位图)+智能web端高保真大数据动态可视化大屏看板+中国动态地图+智慧电商实时动态数据大屏看板
  15. JM代码阅读之一SODB RBSP EBSP NALU
  16. Windows文件系统-NTFS文件系统
  17. 若依框架登录去除验证码
  18. pc版qq登录及移动版qq登录的申请过程
  19. IDEA中怎么调出右下角的版本控制Git
  20. 结对第一次—原型设计(文献摘要热词统计)

热门文章

  1. 联想小新无线网总断问题
  2. window 10 专业版激活 及去掉 window defender
  3. 微信记录删除后怎么不被恢复呢?掌握这几个彻底删除的技巧!
  4. OpenCV之开运算与闭运算
  5. 【原】Gatling笔记
  6. 【DIV 盒子模型】
  7. revit 二次开发——在墙上挖圆形洞(Create Circle openning in wall)
  8. Standford CoreNLP
  9. MYSQL8.0 WITH RECURSIVE递归查询
  10. 【网络】三层交换机配置 VLAN