BAT经典面试题:操作系统题目

来源:互联网 发布:raft算法 编辑:程序博客网 时间:2024/05/21 15:01

1. 同样可以实现互斥,互斥锁和信号量有什么区别?

答:信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作(大家都在semtake的时候,就阻塞在哪里)。而互斥锁是用在多线程多任务互斥的,一个线程占用了某一个资源,那么别的线程就无法访问,直到这个线程unlock,其他的线程才开始可以利用这 个资源。比如对全局变量的访问,有时要加锁,操作完了,在解锁。有的时候锁和信号量会同时使用的”

也就是说,信号量不一定是锁定某一个资源,而是流程上的概念,比如:有A,B两个线程,B线程要等A线程完成某一任务以后再进行自己下面的步骤,这个任务 并不一定是锁定某一资源,还可以是进行一些计算或者数据处理之类。而线程互斥量则是“锁住某一资源”的概念,在锁定期间内,其他线程无法对被保护的数据进 行操作。在有些情况下两者可以互换。

区别:

  • 作用域上
    信号量:进程间或线程间(linux仅线程间的无名信号量pthread semaphore)
    互斥锁:线程间。

  • 上锁时
    信号量:只要信号量的value大于0,其他线程就可以sem_wait成功,成功后信号量的value减一。若value值不大于0,则sem_wait使得线程阻塞,直到sem_post释放后value值加一,但是sem_wait返回之前还是会将此value值减一。
    互斥锁:只要被锁住,其他任何线程都不可以访问被保护的资源。

2.简述Linux进程内存空间分为哪几个段?作用分别是什么?

参见博文。

3.简述Linux内存分配–伙伴系统 原理

答:伙伴系统的伙伴,简单来说体现在分配内存时,找到能够满足条件的最小的块;如果找不到就找大的块,然后将其一分为2,分配一块,留一块;回收时如果有相邻的同样大小的块,则合并。

这样的目的:最大限度的降低内存的碎片化

原理:

  • 将内存块分为了11个连续的页框块(1,2,4,8….512,1024),其中每一个页框块中用链表将内存块对应内存大小的块进行链接。
  • 若需要一块256大小的内存块,则从对应的256链表中查找空余的内存块,若有则分配。否则查找512等等。
  • 若在256中未找到空余内存块,在512中查找到空余的内存块。则将512分成大小相等的两部分互为伙伴,一部分进行分配,另一部分则插入256链表中。
  • 内存的释放过程与分配过程相反。在分配过程中由大块分解而成的小块中没有被分配的块将一直等着被分配的块被释放,从而和其合并。最终相当于没有划分小块。不是伙伴不合并。

4.简述Malloc实现原理

答:malloc函数由程序员调用,编译器在内存的堆区中分配空间。可以基于伙伴系统实现,也可以使用基于链表的实现 。

  • 堆中的区域不连续。系统将堆上所有空闲内存块连成链表,每个节点记录空闲内存块的地址、大小等信息
  • 分配内存时,遍历链表,找到大小合适的块,伙伴系统中,将其一分为二,一分给用户,一份放回空闲链表合适位置
  • free时,直接把内存块返回链表,伙伴系统检测到两块后将其合并
  • 解决外部碎片:将能够合并的内存块进行合并

5. 使用mmap读写文件为什么比普通读写函数要快?

答:常规文件操作为了提高读写效率和保护磁盘,使用了页缓存机制。这样造成读文件时,需要先将文件页从磁盘拷贝到页缓存中,由于页缓存处在内核空间,不能被用户进程直接寻址,所以还需要将页缓存中数据页再次拷贝到内存对应的用户空间中。这样,通过了2次数据拷贝过程,才能完成进程对文件内容的获取任务。写操作一样,待写入的buffer在内核空间不能直接访问,必须要先拷贝至内核空间对应的主存,再写回磁盘中(延迟写回),也是需要两次数据拷贝。

这里写图片描述

图中从上到下的三个位置依次表示:
1. 文件在磁盘中的存储地址;
2. 内核维护的文件的cache(也叫做page cache,4k为一页,每一页是一个基本的cache单位);
3. 用户态的buffer(read函数中分配的那段内存)

发起一次读请求后,内核会先看一下,要读的文件是否已经缓存在内核的页面里面了。如果是,则直接从内核的buffer中复制到用户态的buffer里面。如果不是,内核会发起一次对文件的IO,读到内核的cache中,然后才会拷贝到buffer中。

mmap内存映射文件之后,操作内存即是操作文件,可以省去不少系统内核调用(lseek, read, write)。

进程启动映射过程,并在虚拟地址空间中为映射创建虚拟映射区域。调用内核空间的系统调用函数mmap(不同于用户空间函数),实现文件物理地址和进程虚拟地址的一一映射关系。进程发起对这片映射空间的访问,引发缺页异常,实现文件内容到物理内存(主存)的拷贝。通过已经建立好的映射关系,只使用1次数据拷贝,就从磁盘中将数据传入内存的用户空间中,供进程使用。

总而言之,常规文件操作需要从磁盘到页缓存再到用户主存的两次数据拷贝。而mmap操控文件,只需要从磁盘到用户主存的一次数据拷贝过程。说白了,mmap的关键点是实现了用户空间和内核空间的数据直接交互而省去了空间不同数据不通的繁琐过程。因此mmap效率更高。

参考:http://www.cnblogs.com/huxiao-tee/p/4660352.html

缺点:

mmap的特点是按需调页。文件如果很小,比如是小于4k的,比如60bytes,由于在内存当中的组织都是按页组织的,将文件调入到内存当中是一个页4k,这样其他的4096-60=4036 bytes的内存空间就会浪费掉了。当mmap的文件是page size的整数倍的时候,使用mmap调用看起来是最合适的,不会造成浪费。

文件无法完成拓展,因为mmap到内存的时候,你所能够操作的范围就确定了,无法增加文件的长度。

如果系统频繁的使用mmap操作,而且每次mmap的size都不同,那么就会使得内存可能缺少足够的连续的内存空间。