10 操作系统

1.进程和线程的区别

进程是具有一定功能的程序关于某个数据集合的 一次运行活动,是系统资源分配和调度的一个独立单位。如运行程序,系统创建一个进程,并分配资源,包括各种表格,内存空间,磁盘空间,I/O等,然后该进程被放到进程的就绪队列里,进程调度程序选中,为其分配cpu时间,这个进程就运行了

线程是进程的一个实体,是cpu调度和分配的基本单位,同一个进程的线程共享进程拥有的资源。

在线程的操作系统中,进程就是资源分配的基本单位,线程是调度的基本单位,是系统并发执行的单元。

  引入线程的优点:

     易于调度,提高并发性,开销小(创建线程的开销小于进程),有利于发挥多处理器的功能(每个线程跑在一个处理器上)。

  区别在于:

    线程属于一个进程,进程可以有多线程。

    属于一个进程的所有线程共享进程的资源,包括打开的文件,Socket等。进程是互相独立的。

    线程类似于轻量级进程,有线程控制块,比进程控制块PCB要小,且切换代价小。

    每个进程有独立的内存空间,线程共享进程内存。

程序可以有多个进程,进程可以有多个线程。


2.线程同步有哪些机制

同步互斥的机制基本有4种方法,临界区,互斥量,信号量和事件。

临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。

互斥量:为协调对一个资源的单独访问而设计,只有拥有互斥对象的线程可以访问系统的公共资源。不仅可以实现应用程序内的公共资源的共享,还可以实现不同程序对公共资源的共享。

信号量:为控制一个具有 有限数量的用户资源而设计的,允许多个线程同时访问一个资源,但限制同一时间的访问此资源的最大线程数。

事件:用来通知线程有一些事情已经发生,从而启动后继任务的开始。

http://www.cnblogs.com/lebronjames/archive/2010/08/11/1797702.html


3.内核线程和用户线程的区别

内核线程是由操作系统管理,建立,销毁的线程。是内核的分身。。内核线程的使用是廉价的,唯一使用的资源就是内核栈和上下文切换时保存寄存器的空间。支持多线程的内核叫做多线程内核(Multi-Threads kernel )。

用户线程是在用户空间里创建,其完全建立在用户空间的线程库,用户线程的建立,同步,销毁,调度完全在用户空间完成,不需要内核的帮助。因此这种线程的操作是极其快速的且低消耗的。缺点是一个线程阻塞,会导致整个进程挂起。因为在操作系统看来,并不识别用户线程,是完全对一个用户进程进行管理的。

解决办法是用户线程+LMP

引入用户线程的优点:

可以在不支持线程的操作系统实现多线程。。(现在哪还有不支持的)

创建,销毁,切换的代价比内核线程小的多。

允许每个进程使用自己的调度算法,比较灵活。

线程可用的表空间和堆栈空间比 内核线程多。

http://blog.sina.com.cn/s/blog_446b43c10100cius.html

10.2内存管理

10.2.1.内存管理的常见的方式:

 块式管理,页式管理,段式和段页式管理。最常用的是段页式管理。

1.把主存分成固定块,容易浪费。

2.页式:分成一页页,小于块,利用率高一些。

3.段式:主存分成小段,利用率更高,但一个程序可能被分为很多段,很多时间用在计算每一段的物理地址。

4.段页式:结合了段式管理和页式管理的优点。把主存分为若干页,每一页又分为若干段。

http://blog.csdn.net/firefly_2002/article/details/8008774


10.2.2分页和分段

页是物理单位,分页实现了离散分配的方式。提高了内存利用率。页是信息的逻辑单位,含有一组其意义相对完整的信息。分段的目的是为了更好的满足用户的需求。页的大小固定,由系统决定,逻辑地址分为页号和页内地址。段的长度不固定,决定于用户所写的程序。


10.2.3虚拟内存

简称虚存,利用磁盘空间模拟内存空间。使应用程序认为它拥有连续可用的内存(一个连续完整的地址空间),允许程序员编写并运行比实际系统内存要大的程序。

实际上,它被分割成多个物理内存碎片,还有部分暂时存储在外部存储器上,在需要时进行数据交换。

优点:

1.扩大地址空间,无论是页式虚存,段式虚存,还是段页式虚存,寻址空间都比实存大。

2.内存保护:每个进程运行在各自的虚拟内存中,互相不能干扰到对方,另外,虚存还对特定的内存地址提供读写保护,可以防止代码或数据被恶意篡改。

3.公平分配内存:采用虚存后,每个进程可以获取同样大小的虚存。

4.当进程需要通信时,可以使用虚存共享的方式实现。

虚存的代价:

1.虚存的管理需要建立很多数据结构,这些需要占用内存。

2.虚拟地址重定位到物理地址,增加了指定执行时间。

3.页面换入换出需要磁盘I/O,很耗费时间。

4.如果一页中只有一部分数据,会浪费内存。


10.2.4内存碎片,内碎片,外碎片

1.内存碎片:由于多处内存分配,造成一小部分内存不能被其他程序使用。

2内碎片:分配给程序的内存空间没有用完,存在于区域内部或 页面内存的存储块。

3.外碎片:由于碎片太小,不能用来分配给新的进程,这部分碎片不属于任何进程,是可分配状态,但是太小造成不能利用。(总和够,但是地址不连续等问题)


10.2.5虚拟地址,逻辑地址,线性地址,物理地址的区别

1.虚拟地址是指:由程序产生的由段选择符合段内偏移地址组成的地址。

2.逻辑地址:是指由程序产生的段内偏移地址,有时直接把逻辑地址当成虚拟地址,两者并无明显的界限。

3.线性地址:是指虚拟地址转换到物理地址的中间层, 是处理器可寻址的内存空间(称为线性地址空间)中的地址。段基址+段偏移形成线性地址。没有分页的话,就是物理地址,如果有分页还要加上页变化转成成物理地址。

4.物理地址: cpu外部地址总线上寻址物理内存的地址信号。


10.2.6 cache的替换算法

.cpu处理速度快,容量小。内存容量大,速度慢,需要cache作为中间过渡。

cache替换算法有随机算法,FIFO算法,LRU算法,LFU算法和OPT算法

程序的局部性原理,即程序的地址访问流有很强的时序相关性,未来的访问模式与最近已发生的访问模式相似。根据这一局部性原理,把主存储器中访问概率最高的内容存放在Cache中,当CPU需要读取数据时就首先在Cache中查找是否有所需内容,如果有则直接从Cache中读取;若没有再从主存中读取该数据,然后同时送往CPU和Cache。

随机算法(RAND),利用随机数产生块号,将其换出,命中率低。

FIFO算法:最先进入的,最早出。 没有利用程序的局部性原理,命中率低。如循环程序。方法简单,方便。

LRU算法:近期最少使用的换出。比较好的利用程序的局部性原理,需要随时记录各块的使用情况。设计较为复杂,开销较大。

                   实现LRU算法的策略:1.计数器法,缓存的每一个块都设置一个计数器,新调用的或者命中的置为0,没有命中的+1;

LFU算法:LFU(Least Frequently Used)最近最少使用算法。它是基于“如果一个数据在最近一段时间内使用次数很少,那么在将来一段时间内被使用的可能性也很小”的思路。为了能够淘汰最少使用的数据,因此LFU算法最简单的一种设计思路就是 利用一个数组存储 数据项,用hashmap存储每个数据项在数组中对应的位置,然后为每个数据项设计一个访问频次,当数据项被命中时,访问频次自增,在淘汰的时候淘汰访问频次最少的数据。这样一来的话,在插入数据和访问数据的时候都能达到O(1)的时间复杂度,在淘汰数据的时候,通过选择算法得到应该淘汰的数据项在数组中的索引,并将该索引位置的内容替换为新来的数据内容即可,这样的话,淘汰数据的操作时间复杂度为O(n)。 

注意LFU和LRU算法的不同之处,LRU的淘汰规则是基于访问时间,而LFU是基于访问次数的。

http://www.cnblogs.com/dolphin0520/p/3749259.html


10.3 用户编程接口

10.3.1  库函数和系统调用的区别

库函数是语言或应用程序的一部分,运行在用户空间,提供系统调用的真正接口。函数库调用属于语言或程序,系统调用属于操作系统的一部分。

库函数调用通常比行内代码慢,因为函数调用的代价。系统调用会更慢,因为要切换上下文到内核模式。


10.3.2 静态链接和动态链接

静态链接就是把要调用的函数和过程都放在执行文件exe中,成为可执行文件的一部分。该文件包含了运行所需的全部代码,静态链接的缺点是当多个程序调用这个函数时,内存会有函数的多个拷贝,造成浪费。

动态链接是把需要的函数代码放在dll(动态链接库),当应用程序被加载到内存中时,根据exe中所加入的重定位信息,调用dll中的函数代码。

静态链接库是lib,库中的代码都要在最后链接到可执行文件中去。 所有静态链接的exe要较大。

动态链接库是一个包含了可由多个程序同时使用的代码和数据的库。它包含函数和数据的模块的集合。程序文件在运行时加重这些模块(所需模块映射到调用进程的地址空间)

相同点:都实现了代码的共享。不同的是:lib不能再包含其他dll和lib,dll里可以包含其他dll和lib。


10.3.4 用户态和核心态

用户态:非特权态,访问资源有限制。

核心态:特权态,root权限。

http://technet.microsoft.com/zh-cn/library/ff554836

10.3.5 用户栈和内核栈的区别

内核在创建进程的时候,创建task_struct同时会分配两个栈:用户栈和内核栈。

用户栈存在于用户空间,内核栈存在于内核空间。当程序在用户空间运行时,cpu堆栈指针寄存器指向的是用户堆栈地址。

当进程使用系统调用进入内核态时,先保存用户栈地址到内核栈中,然后设置堆栈指针寄存器为内核栈地址,运行后恢复到用户栈。








  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值