操作系统知识点总结

进程与线程的区别

1.进程是系统进行资源分配的基本单位,有独立的内存地址空间;线程是CPU调度的基本单位,没有单独的地址空间,
有独立的栈,局部变量,寄存器,程序计数器等。

2.创建进程开销大,包括创建虚拟地址空间等需要大量系统资源;创建线程开销小,基本上只有一个内核对象和一个
堆栈。

3.一个进程无法直接访问另一个进程的资源;同一个进程内的多个线程共享进程的资源。

4.进程切换开销大(涉及当前执行进程CPU环境的保存以及新调度的进程CPU环境的设置),线程切换开销小(只需保
存和设置少量寄存器的内容);进程间通信开销大(需要借助操作系统),线程间通信开销小(可以直接读写进程数
据段,如全局变量)。

5.线程属于进程,不能独立执行。每个进程至少要有一个线程,成为主线程。

进程通信的几种方式

1.管道(Pipe)及有名管道(namedpipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的
限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信;

2.信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程
还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数
sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新
实现了signal函数);

3.Message(消息队列):消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以
向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承
载无格式字节流以及缓冲区大小受限等缺点。

4.共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设
计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。

5.信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。

6.套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支
开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。

线程同步的几种方式

线程同步的方式主要由4种:   
    临界区(Critical Section)
    互斥量(Mutex)
    信号量(Semaphore)
    事件(Event)

主要区别和特点如下:
1.临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。在任意时刻只允许一个线
程对共享资源进行访问,如果有多个线程试图访问公共资源,那么在有一个线程进入后,其他试图访问公共资源的线程
将被挂起,并一直等到进入临界区的线程离开,临界区在被释放后,其他线程才可以抢占。

2.互斥量:采用互斥对象机制。只有拥有互斥对象的线程才有访问公共资源的权限,因为互斥对象只有一个,所以能保
证公共资源不会同时被多个线程访问。互斥不仅能实现同一应用程序的公共资源安全共享,还能实现不同应用程序的公
共资源安全共享。

3.信号量:它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。

4.事件:通过通知操作的方式来保持线程的同步,还可以方便实现对多个线程的优先级比较的操作。

用户级线程和内核级线程

1.用户级线程(user level thread)。对于这类线程,有关线程管理的所有工作都由应用程序完成,内核意识不到线程
的存在。在应用程序启动后,操作系统分配给该程序一个进程号,以及其对应的内存空间等资源。应用程序通常先在一个
线程中运行,该线程被称为主线程。在其运行的某个时刻,可以通过调用线程库中的函数创建一个在相同进程中运行的新
线程。
用户级线程的好处是非常高效,不需要进入内核空间,但并发效率不高。

2.内核级线程(kernel level thread)。对于这类线程,有关线程管理的所有工作由内核完成,应用程序没有进行线程
管理的代码,只能调用内核线程的接口。内核维护进程及其内部的每个线程,调度也由内核基于线程架构完成。
内核级线程好处是内核可以将不同线程更好的分配到不同的CPU,以实现真正的并行计算。

事实上,在现代操作系统中,往往使用组合方式实现多线程,即线程创建完全在用户空间中完成,并且一个应用程序中的
多个用户级线程被映射到一些内核级线程上,相当于是一种折中方案。

用户栈和内核栈的区别

操作系统中,每个进程会有两个栈,一个用户栈,存在于用户空间,一个内核栈,存在于内核空间。当进程在用户空间运
行时,cpu堆栈指针寄存器里面的内容是用户堆栈地址,使用用户栈;当进程在内核空间时,cpu堆栈指针寄存器里面的内
容是内核栈空间地址,使用内核栈。

内核栈是内存中属于操作系统空间的一块区域,其主要用途为:
    1.保存中断现场,对于嵌套中断,被中断程序的现场信息依次压入系统栈,中断返回时逆序弹出;

    2.保存操作系统子程序间相互调用的参数、返回值、返回点以及子程序(函数)的局部变量。

用户栈是用户进程空间中的一块区域,用于保存用户进程的子程序间相互调用的参数、返回值、返回点以及子程序(函数)
的局部变量。

那么为什么不直接用一个栈,何必浪费那么多的空间呢?
    1.如果只用系统栈。系统栈一般大小有限,如果中断有16个优先级,那么系统栈一般大小为15(只需保存15个低
    优先级的中断,另一个高优先级中断处理程序处于运行),但用户程序子程序调用次数可能很多,那样15次子程
    序调用以后的子程序调用的参数、返回值、返回点以及子程序(函数)的局部变量就不能被保存,用户程序也就无
    法正常运行了。

    2.如果只用用户栈。我们知道系统程序需要在某种保护下运行,而用户栈在用户空间(即cpu处于用户态,而cpu
    处于核心态时是受保护的),不能提供相应的保护措施(或相当困难)。

内存池,进程池,线程池

概念“池化技术 ”。池化技术一言以蔽之就是:提前保存大量的资源,以备不时之需以及重复使用。池化技术应用广泛,
如内存池,线程池,连接池等等。内存池相关的内容,建议看看Apache、Nginx等开源web服务器的内存池实现。

由于在实际应用当中,分配内存、创建进程、线程都会涉及到一些系统调用,系统调用导致程序从用户态切换到内核态,
是非常耗时的操作。因此,当程序中需要频繁的进行内存申请释放,进程、线程创建销毁等操作时,通常会使用内存池、
进程池、线程池技术来提升程序的性能。

线程池:线程池的原理很简单,类似于操作系统中的缓冲区的概念,它的流程如下:先启动若干数量的线程,并让这些线
程都处于睡眠状态,当需要开辟一个线程去做具体的工作时,就会唤醒线程池中的某一个睡眠线程,让它去做具体工作,
当工作完成后,线程又处于睡眠状态,而不是将线程销毁。

进程池与线程池同理。

内存池:内存池是指程序预先从操作系统申请一块足够大内存,此后,当程序中需要申请内存的时候,不是直接向操作系
统申请,而是直接从内存池中获取;同理,当程序释放内存的时候,并不真正将内存返回给操作系统,而是返回内存池。
当程序退出(或者特定时间)时,内存池才将之前申请的真正内存释放。

死锁

所谓死锁是指多个进程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都无法向前推进。

产生死锁的原因:
    1.系统资源的竞争。

    2.进程推进顺序非法。

产生死锁的必要条件:
    1.互斥条件:一个资源每次只能被一个进程使用。

    2.不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。

    3.请求和保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

    4. 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

    这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发
    生死锁。

银行家算法
    银行家算法是著名的死锁避免算法。允许进程动态的申请资源,但系统在分配资源之前应先计算此次分配资源的
    安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。

进程调度算法

先来先服务算法(FCFS)
短作业优先算法(SJF):平均等待时间,平均周转时间最少
优先级调度算法
高响应比调度算法:即有利于短作业又兼顾长作业,响应比 = (等待时间 + 要求服务时间)/ 要求服务时间
时间片轮转算法
多级反馈队列调度算法

内存分配管理方式(块式、页式、段式、段页式)

块式管理
    把主存分为一大块、一大块的,当所需的程序片段不在主存时就分配一块主存空间,把程序片段载入主存,就算
    所需的程序片段只有几个字节也只能把这一块分配给它。这样会造成很大的浪费,但易于管理。

页式管理
    把主存分为一页一页的,每一页的空间要比一块一块的空间小很多,显然这种方法的空间利用率要比块式管理高
    很多。

段式管理
    把主存分为一段一段的,每一段的空间又要比一页一页的空间小很多,这种方法在空间利用率上又比页式管理高
    很多,但是也有另外一个缺点。一个程序片断可能会被分为几十段,这样很多时间就会被浪费在计算每一段的物
    理地址上。

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

静态链接和动态链接

静态链接就是在编译链接时直接将需要的执行代码拷贝到调用处,优点就是在程序发布的时候就不需要的依赖库,也就是
不再需要带着库一块发布,程序可以独立执行,但是体积可能会相对大一些。

动态链接就是在编译的时候不直接拷贝可执行代码,而是通过记录一系列符号和参数,在程序运行或加载时将这些信息传
递给操作系统,操作系统负责将需要的动态库加载到内存中,然后程序在运行到指定的代码时,去共享执行内存中已经加
载的动态库可执行代码,最终达到运行时连接的目的。优点是多个程序可以共享同一段代码,而不需要在磁盘上存储多个
拷贝,缺点是由于是运行时加载,可能会影响程序的前期执行性能。

虚拟内存

基于局部性原理,在程序装入时,可以将程序的一部分装入内存,而将其余的部分留在外存,就可以启动程序执行。在程
执行的过程中,当所访问的信息不在内存时,由操作系统将所需要的部分调入内存,然后继续执行程序。另一方面,操作
系统将内存中暂时不使用的内容换出到外存上,从而腾出空间存放将要调入内存的信息。这样系统就好像为用户提供了一
个比实际内存大的多的存储器,称为虚拟存储器。

虚拟内存实现由以下三种方式:
    1.请求分页存储管理
    2.请求分段存储管理
    3.请求段页式存储管理

所需硬件支持:
    1.一定容量的内存与外存。
    2.页表机制(或段表机制),作为主要的数据结构。
    3.中断机构,当用户程序要访问的部分尚未调入内存,则产生中断。
    4.地址变换机构,逻辑地址到物理地址的变换。

请求分页是目前最常用的一种实现虚拟内存的方法。常用的页面置换算法:
    1.最佳置换算法(OPT)
    2.先进先出页面置换算法(FIFO)
    3.最近最久未使用(LRU)

    工作集(或驻留集)是指在某段时间间隔内,进程要访问的页面集合。经常被使用的页面需要在工作集中,而长
    期不被使用的页面要从工作集中被丢弃。为防止系统出现抖动现象(频繁的换页活动),需要选择合适的工作集
    大小。
    工作集模型的原理是:让操作系统跟踪每个进程的工作集,并为进程分配大于其工作集的物理块。如果还有空闲
    物理块,则可以再调一个进程到内存以增加多道程序数。如果所有工作集之和增加以至于超过了可用物理块的总
    数,那么操作系统会暂停一个进程,将其页面调出并且将其物理块分配给其他进程,防止出现抖动现象。

猜你喜欢

转载自blog.csdn.net/qq_39026548/article/details/80739411