操作系统笔记
进程
是应用程序执行副本,操作系统资源分配最小单位
进程有很多东西,但是我们执行只需要CPU和内存(程序编译成2进制存入内存,然后CPU去读取内存中的指令一条条执行,不需要进程),于是抽象出了线程
应用启动就变成进程,进程会先拿到一个主线程,这个主线程再去操作系统申请线程
线程
OS分配执行程序的最小单位(执行程序指的kernal thread,应用程序的thread 和kernal thread存在映射关系);只需要程序和CPU;所有的进程启动以后必然有一个主线程。
(1)real thread
用户实在自己的空间创建线程,而OS只调度自己的线程,所以用户的线程需要挂靠/映射到OS的线程中,因为这样才能真的执行。所以只有kernal thread才是真的thread。
(2)进程线程区别
进程是拿资源的,线程是执行程序的,他俩关联性可以不强。
(3)Thread pool
高并发场景下的思想:
(4)线程切换
阻塞状态是由操作系统内核来进行切换:要存储当前线程的cpu状态,进入调度器,调度完又加载CPU状态;
如果任务很小,这样线程频繁切换,很不划算,于是想到了将所有task抽象成更小的模型:routine。
(5)线程的几种可用状态
1.创建(new)
建立一个新线程,新生的线程将处于新建状态。此时它已经有了相应的主存空间和其他资源,并已经被初始化。
2.准备(runnable)
线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权 。
3.阻塞状态(blocked)
阻塞状态是指线程因为某种原因放弃了cpu 使用权,也即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状态,才有机会再次获得cpu timeslice 转到运行(running)状态。阻塞的情况分三种:
- 等待阻塞:运行(running)的线程执行o.wait()方法,JVM会把该线程放入等待队列(waitting queue)中。
- 同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。
- 其他阻塞:运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。
4.运行状态(running)
可运行状态(runnable)的线程获得了cpu 时间片(timeslice) ,执行程序代码。
5.死亡状态(dead)
线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。
协程
比线程更小,协程的暂停完全由程序控制(也就是在用户态执行)。
Routine的一种实现(轻量级线程)
高IO,任务很多的情况下创建routine,切换成本更低,是轻量级线程。
并发和并行
1.并发
指宏观上在一段时间内能同时运行多个程序
OS通过引入进程和线程,使得程序能够并发运行
2.并行
指同一时刻能运行多个指令。
需要硬件支持,如多流水线、多核处理器或者分布式计算系统。
共享
共享是指系统中的资源可以被多个并发进程共同使用。
有两种共享方式:互斥共享和同时共享。
死锁
并发进程在竞争资源的过程中可能产生死锁。
产生原因
根本原因:系统能够提供的资源个数比请求该资源的进程数要少。当系统中两个或多个进程因申请资源得不到满足而等待时,若各进程都没有能力进一步执行,系统就发生死锁。
产生条件
(1)互斥
多进程共享的资源具有互斥特性,即一次只能由一个进程使用。如果另一个进程申请该资源,那么申请进程必须等待,直到该资源被释放。
(2)不剥夺(非抢占)
进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能 由获得该资源的进程自己来释放(只能是主动释放)。
(3)占有并等待(部分分配)
进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。
(4)环路条件(循环等待)
存在一种进程资源的循环等待链,链中每一个进程已获得的资源同时被 链中下一个进程所请求。
处理方法
- 预防死锁
- 避免死锁
有序资源分配法
银行家算法 - 死锁检测与忽略
如何确保N个线程可以访问N个资源同时又不导致死锁?
只要破坏四个必要条件其中任意一个条件,就可以避免死锁,其中最简单的就是破环循环等待条件。指定获取锁的顺序,并强制线程按照指定的顺序获取锁,按同一顺序访问对象,加载锁,释放锁。
进程通信方式
进程通信是一个进程与另一个进程间共享信息的一种方式。
1.消息队列
(1)消息缓冲通信
(2)信箱通信
2.共享内存
eg.复制粘贴板
最快的一种通信方式,多个进程可同时访问同一片内存空间,相对其他方式来说具有更少的数据拷贝,效率较高。
*3.管道通信
无名管道(PIPE)
系统内核,FIFO
有名管道(MKPIPE)
缓存
4.信号量
5.套接字(SOCKET)
常见的进程调度算法
虚拟
大内核和微内核
中断分类
1.外中断
2.异常
3.陷入
- 本文作者:lybbor
- 版权声明:本博客所有文章均采用 BY-NC-SA 许可协议,转载请注明出处!