进程和线程的区别
进程:是操作系统资源分配的基本单位,进程有独立的地址空间,一个进程当中可以用多个线程。
线程:是操作系统CPU任务调度的基本单位,没有独立的地址空间,但有自己的堆栈和局部变量,满足任务调度的最基本的资源(保存现场,恢复现场),即栈,寄存器。一个进程里的多个线程可以共享该进程的所有资源。
切换开销:
- 进程间切换的开销比较大,因为它们拥有独立的资源。
- 线程间切换的开销相对较小,因为它们共享相同的资源。
进程间通信的方式有哪些
- 无名管道
- 有名管道
- 高级管道
- 消息队列
- 信号
- 信号量
- Socket
- 共享内存(最快)
线程间通信的方式有哪些
锁机制
互斥锁
信号
信号量
条件变量
管道
共享内存
共享内存是什么
共享内存是进程之间共享数据的机制,它允许多个进程访问同一块物理内存区域,从而实现了进程之间的数据共享。
优点是快,不需要内核做任何操作;
缺点是要保证进程之间修改数据的同步工作
死锁产生的必要条件,产生的原因,怎么预防死锁
死锁:由两个及以上的进程由于竞争资源而导致进程都无法执行的情况
- 互斥:一个资源每次只能被一个进程使用
- 不可剥夺:进程已获得的资源,在末使用完之前,不能强行剥夺
- 占有且等待:一个进程因请求资源而阻塞时,对已获得的资源保持不放
- 循环等待:若干进程之间形成─种头尾相接的循环等待资源关系
产生死锁的原因 - 竞争资源
预防死锁 - 有序资源分配法 - 银行家算法
破坏死锁的必要条件:通过破坏四个死锁必要条件之一来预防死锁,比如破坏循环等待条件、破坏占有且等待条件等。
加锁顺序:确保所有进程或线程都按照相同的顺序获取锁资源,从而避免循环等待的情况发生。
资源分配策略:设计有序资源分配法 - 银行家算法。
死锁检测与恢复:实现死锁检测算法,及时发现死锁的发生。
常用的 Linux 命令+GDB 常见的调试命令
常用的 Linux 命令-CSDN博客
内核态和用户态的区别
内核态和用户态是指计算机处理器运行的两种不同的特权级别或权限级别。
内核态: 内核态是操作系统(OS)执行的特权级别。在内核态下,操作系统具有对系统硬件和资源的完全访问权限,并可以执行特权指令(例如 I/O 指令、修改内存映射等)。内核态下运行的代码拥有最高的权限,可以执行任何指令并访问系统的所有资源。
用户态: 用户态是普通应用程序执行的特权级别。在用户态下,应用程序只能执行受限制的指令,且无法直接访问系统硬件或修改系统状态。应用程序通常在用户态下运行,它们通过系统调用(System Call)向操作系统请求服务(如文件 I/O、网络通信等),操作系统会在内核态下执行这些服务,并将结果返回给应用程序。
主要区别在于权限和可执行的指令范围:内核态具有最高的权限和完全的系统访问权限,而用户态受到限制,并且只能执行受限制的指令。
进程调度算法有哪些
进程调度算法是操作系统中用于管理和调度进程(或线程)执行的一种策略。它们决定了哪些进程应该在某个时间点执行,以及它们应该如何被分配处理器资源。以下是一些常见的进程调度算法:
先来先服务(非剥夺)
- 这是一种简单的调度算法,按照进程到达的顺序依次执行。新到达的进程排在队列的末尾等待执行。
- FCFS 算法容易实现,但可能会导致长作业等待时间过长,因为它不考虑进程的执行时间长短。
最短作业优先(非剥夺)
- SJF 算法选择下一个执行的进程时,会优先选择执行时间最短的进程。
- 这种算法可以最小化平均等待时间,但需要提前知道每个进程的执行时间,对于实时系统可能无法应用。
最短剩余时间优先(剥夺)
- 是 SJF 的抢占式版本,当一个新的进程到达时,如果它的执行时间比当前正在执行的进程的剩余执行时间还要短,则抢占 CPU 执行。
- SRTF 可以进一步减少等待时间,但需要频繁地进行上下文切换,可能会增加系统开销。
时间片轮转调度(剥夺)
- RR 算法将 CPU 时间划分成一系列时间片,每个进程在一个时间片内执行一定时间,然后被放到队列的末尾等待下一次执行。
- 这种算法适用于时间共享系统,可以保证每个进程得到一定的执行时间,并且响应时间比较短。
优先级调度:(非剥夺+剥夺)
- 优先级调度算法根据进程的优先级来确定下一个执行的进程。优先级可以是静态的,也可以是动态的。
- 可以根据进程的特性、重要性等因素来动态调整优先级,以优化系统性能。
什么是孤儿进程,什么是僵尸进程,如何解决僵尸进程
孤儿进程:
孤儿进程是指父进程结束后,子进程还在继续运行。孤儿进程会被
init
进程(通常进程编号为1)接管。僵尸进程:
僵尸进程是指一个子进程已经结束,但是它的父进程还没有调用
wait()
或waitpid()
等系统调用来获取子进程的状态信息,子进程的进程控制块会保留在系统进程表中,此时子进程的状态被标记为僵尸进程。僵尸进程会占用系统资源。
解决僵尸进程的方法:
解决僵尸进程的方法通常包括以下几种:
- 父进程调用
wait()
或waitpid()
等系统调用来获取子进程的状态信息。- 通过信号机制,子进程退出后向父进程发送
SIGCHLD
信号,父进程调用wait()
或waitpid()
回收子进程的资源。- 杀死父进程,僵尸进程会变成孤儿进程由init进程接管。
- 重启系统,杀死所有进程。
进程有多少种状态,如何转换
进程有五种状态:创建、就绪、执行、阻塞、终止:
- 创建状态:一个进程启动,首先进入创建状态,需要获取系统资源创建进程管理块完成资源分配。
- 就绪状态:在创建状态完成之后,进程已经准备好,处于就绪状态,但是还未获得CPU资源,无法运行。
- 运行状态:获取处理器资源,被系统调度,当具有时间片开始进入运行状态。如果进程的时间片用完了就进入就绪状态。
- 等待状态:在运行状态期间,如果进行了阻塞的操作,此时进程暂时无法操作就进入到了阻塞状态,在这些操作完成后就进入就绪状态。等待再次获取处理器资源,被系统调度,当具有时间片就进入运行状态。
- 终止状态:进程结束或者被系统终止,进入终止状态。
进程状态转换图