计算机基础知识了解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zglwy/article/details/81712747

 linux文件系统:
 先说一下格式化:每种操作系统所设置的文件属性/权限并不相同,为了存放这些文件所需的数据,因此就需要将分区格式化,以成为操作系统能够利用的文件系统格式。linux的文件格式为Ext2/Ext3,现在好像已经到了Ext4.windows 操作系统为vfat或者NTFS。
linux文件系统:
  操作系统的文件数据除了文件实际内容外,还有非常多的属性,如文件权限(rwx)与文件属性(所有者、群组、时间参数等)。
  文件系统通常将这两部分数据存放在不同的块。权限属性放到 inode 中,实际数据放到 data block 中。
  还有一个超级块(super block)会记录文件系统的整体信息,包括 inode 与block 的数量、使用量等。

  inode:记录文件属性,一个文件占用一个inode,同时记录此文件的数据所在的block号码;
  block:实际记录文件的内容,若文件太大时会占用多个 block ;
  super block:记录文件系统的整体信息,包括inode/block 的总量、使用量、剩余量,以及文件系统的格式与相关信息等。
 
每个inode与block都有编号,而每个文件系统都会占用一个inode,inode中有文件数据放置的block号码。我们可以找到文件的inode,然后找出文件所放置数据的block号码,之后读出数据。
这种数据访问方式成为索引式文件系统。这种文件系统一般不太需要经常进行磁盘碎片整理。
而 U 盘等为FAT文件格式,每个block号码都记录在前一个block号码中,因此数据的读取性能较差,用久了得进行碎片整理。

普通文件的block块存储的是文件内容,目录的block块则存储了该目录下所有文件的inode号及对应的文件名等信息。


虚拟内存:
    WINDOWS运用了虚拟内存技术,即拿出一部分硬盘空间来充当内存使用,这部分空间即称为虚拟内存,虚拟内存在硬盘上的存在形式就是 PAGEFILE.SYS这个页面文件。

虚拟内存地址:
    什么是虚拟内存地址和物理内存地址呢。假设你的计算机是32位,那么它的地址总线是32位的,也就是它可以寻址0~0xFFFFFFFF(4G)的地址空间,
但如果你的计算机只有256M的物理内存0x~0x0FFFFFFF(256M),同时你的进程产生了一个不在这256M地址空间中的地址,那么计算机该如何处理呢?回答这个问题前,先说明计算机的内存分页机制。
    计算机会对虚拟内存地址空间(32位为4G)分页产生页(page),对物理内存地址空间(假设256M)分页产生页帧(page frame),这个页和页帧的大小是一样大的,
所以呢,在这里,虚拟内存页的个数势必要大于物理内存页帧的个数。在计算机上有一个页表(page table),就是映射虚拟内存页到物理内存页的,更确切的说是页号到页帧号的映射,而且是一对一的映射。
但是问题来了,虚拟内存页的个数 > 物理内存页帧的个数,岂不是有些虚拟内存页的地址永远没有对应的物理内存地址空间?不是的,操作系统是这样处理的。操作系统有个页面失效(page fault)功能。
操作系统找到一个最少使用的页帧,让他失效,并把它写入磁盘,随后把需要访问的页放到页帧中,并修改页表中的映射,这样就保证所有的页都有被调度的可能了。这就是处理虚拟内存地址到物理内存的步骤。

内存映射:
    虚拟内存的目标存储器是磁盘,所以虚拟内存区域是和磁盘中的文件对应的。初始化虚拟内存区域的内容时,会把虚拟内存区域和一个磁盘文件对象对应起来,这个过程叫内存映射(memory mapping)
    由于内存映射机制,所以一个磁盘文件对象可以被多个进程共享访问,也可以被多个进程对象私有访问。如果是共享访问,那么一个进程对这个对象的修改会显示到其他进程。如果是私有访问,
内核会采用写时拷贝copy on write的方式,如果一个进程要修改一个私有的写时拷贝的对象,会产生一个保护故障,内核会拷贝这个私有对象,写进程会在新的私有对象上修改,
其他进程仍指向原来的私有对象。
理解了内存映射机制就可以理解几个重要的函数:
    1. fork函数会创建带有独立虚拟地址空间的新进程,内核会为新进程创建各种数据结构,分配一个唯一的PID,把当前进程的mm_struct, area结构和页表都复制给新进程。
两个进程的共享同样的区域,这些区域包括共享的内存映射和私有的内存映射。私有的内存映射区域都被标记为私有的写时拷贝。如果新建的进程对这些虚拟页做修改,
那么会触发写时拷贝,为新的进程维护私有的虚拟地址空间。
    
    2. mmap函数可以创建新的虚拟内存area,并把磁盘对象映射到新建的area。
mmap可以用作高效的操作文件的方式,直接把一个文件映射到内存,通过修改内存就相当于修改了磁盘文件,减少了普通文件操作的一次拷贝操作。
普通文件操作时会先把文件内容从磁盘复制到内核空间管理的一块虚拟内存区域area,然后内核再把内容复制到用户空间管理的虚拟内存area。 
mmap相当于创建了一个内核空间和用户空间共享的area,文件的内容只需要在这个area对应的物理内存和磁盘文件之间交换即可。


从文件IO的角度来说,Linux把一切IO都抽象成了文件,比如普通文件IO,网络IO,统统都是文件,利用open系统调用返回一个整数作为文件描述符file descriptor,
进程可以利用file descriptor作为参数在任何系统调用中表示那个打开的文件。内核为进程维护了一个文件描述符表来保持进程所有获得的file descriptor。

操作系统利用fork系统调用来创建一个子进程。fork所创建的子进程会复制父进程的虚拟地址空间。
要理解“复制”和“共享”的区别,复制的意思是会真正在物理内存复制一份内容,会真正消耗新的物理内存。共享的意思是使用指针指向同一个地址,不会真正的消耗物理内存。
理解这两个概念的区别很重要,这是进程和线程的根本区别之一。

进程间通信:
两个进程不能通过简单的共享变量的方式来进行进程间通信,也就是说进程不能通过直接共享内存的方式来进行进程间通信,只能采用信号,管道等方式来进行进程间通信。这样的效率肯定比直接共享内存的方式差

clone系统调用:
在Linux系统中,线程是使用clone系统调用,clone是一个轻量级的fork,它提供了一系列的参数来表示线程可以共享父类的哪些资源,比如页表,打开文件表等等。我们上面说过了共享和复制的区别,共享只是简单地用指针指向同一个物理地址,不会在父进程之外开辟新的物理内存。
clone系统调用可以指定创建的线程开始执行代码位置,也就是Java中的Thread类的run方法

展开阅读全文

没有更多推荐了,返回首页