进程、线程、死锁

进程

  进程:系统进行资源分配和调度的一个独立单位。每一个进程都有一个自己的地址空间,即进程空间或(虚空间)。进程有 5 种基本状态:创建、就绪、阻塞、执行、终止。
          进程状态转换图

线程

  线程:CPU调度的一个基本单位。线程与同属一个进程的其他线程共享进程所拥有的全部资源。线程有 3 个基本状态:就绪、执行、阻塞。

进程和线程的区别

  1. 进程是资源的分配和调度的一个独立单元,而线程是CPU调度的基本单元
  2. 进程拥有独立的资源,而各线程共享所属进程的所有资源(寄存器、堆栈等)
  3. 进程结束后它拥有的所有线程都将销毁,而线程的结束不会影响同个进程中的其他线程
  4. 一个程序至少有一个进程,一个进程至少有一个线程
  5. 线程中执行时一般都要进行同步和互斥,因为他们共享同一进程的所有资源

并行和并发

  • 并行:CPU同时计算(一场象棋比赛)
  • 并发:CPU通过调度算法计算(一局象棋对战)

死锁

  死锁是指多个进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。
  死锁产生的必要条件(只要其中任一条件不成立,死锁就不会发生):

  • 互斥条件:进程对所分配的资源进行排他性控制,即在一段时间内某资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待。
  • 不剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能 由获得该资源的进程主动释放。
  • 请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源 已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。
  • 环路等待条件:存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。

避免死锁

  可通过以下三种手段避免死锁:
1. 加锁顺序(线程按一定顺序加锁,若所有线程都按相同顺序获得锁,就能避免死锁)
2. 加锁时限(线程获取锁时加上时限,超时则放弃并释放所占有的锁,就能避免死锁)
3. 死锁检测(一个更优的预防机制,主要针对不可能实现按序加锁和加锁时限的场景)

  每当一个线程获得了锁,便在相关的数据结构中(Map、Graph等)将其记下。当一个线程请求锁失败时,这个线程可以遍历锁的关系图看看是否有死锁发生。
  检测出死锁时,有一种解决方案是给这些线程设置优先级,让一个或多个线程回退,剩下的线程继续保持它们需要的锁。

如果赋予这些线程的优先级是固定不变的,同一批线程总是会拥有更高的优先级。为避免这个问题,可以在死锁发生的时候设置随机的优先级。

猜你喜欢

转载自blog.csdn.net/u012102104/article/details/79490941