操作系统之线程、进程及同步锁

线程与进程概念

进程:进程是系统进行资源分配和调度的一个独立单位。

线程:线程是进程的一个实体,是CPU调度和分派的基本单位,线程自己基本上不拥有系统资源,只拥有一点在系统运行中必不可少的资源,但是它可与同属一个进程的其他线程共享进程所拥有的全部资源。
每一个进程和线程所独自占有的资源如下表所示:

进程占有的资源线程占有的资源
地址空间
全局变量寄存器
打开的文件状态
子进程程序计数器
信号量
账户信息

一、区别

进程VS 线程

  1. 进程采用fork创建,线程采用clone创建
  2. 进程fork创建的子进程的逻辑流位置在fork返回的位置,线程clone创建的KSE的逻辑流位置在clone调用传入的方法位置,比如Java的Thread的run方法位置
  3. 进程拥有独立的虚拟内存地址空间和内核数据结构(页表,打开文件表等),当子进程修改了虚拟页之后,会通过写时拷贝创建真正的物理页。线程共享进程的虚拟地址空间和内核数据结构,共享同样的物理页
  4. 多个进程通信只能采用进程间通信的方式,比如信号,管道,而不能直接采用简单的共享内存方式,原因是每个进程维护独立的虚拟内存空间,所以每个进程的变量采用的虚拟地址是不同的。多个线程通信就很简单,直接采用共享内存的方式,因为不同线程共享一个虚拟内存地址空间,变量寻址采用同一个虚拟内存
  5. 进程上下文切换需要切换页表等重量级资源,线程上下文切换只需要切换寄存器等轻量级数据
  6. 进程的用户栈独享栈空间,线程的用户栈共享虚拟内存中的栈空间,没有进程高效
  7. 一个应用程序可以有多个进程,执行多个程序代码,多个线程只能执行一个程序代码,共享进程的代码段
  8. 进程采用父子结构,线程采用对等结构

一、进程是资源分配的最小单位,线程是程序执行的最小单位(资源调度的最小单位)
二、进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。
三、线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。
四、但是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间

总结:

线程是进程划分成的更小的运行单位,一个进程在其执行的过程中可以产生多个线程。

线程和进程最大的不同在于基本上各进程是独立的,而各线程则不一定,因为同一进程中的线程极有可能会相互影响。

线程执行开销小,但不利于资源的管理和保护;而进程正相反。

二、状态

进程有5种状态

在这里插入图片描述

  • 创建状态(new) :进程正在被创建,尚未到就绪状态。
  • 就绪状态(ready):进程已处于准备运行状态,即进程获得了除了处理器之外的一切所需资源,一旦得到处理器资源(处理器分配的时间片)即可运行。
  • 运行状态(running) :进程正在处理器上上运行(单核CPU下任意时刻只有一个进程处于运行状态)。
  • 阻塞状态(waiting) :又称为等待状态,进程正在等待某一事件而暂停运行如等待某资源为可用或等待 IO操作完成。即使处理器空闲,该进程也不能运行。
  • 结束状态(terminated) :进程正在从系统中消失。可能是进程正常结束或其他原因中断退出运行

在这里插入图片描述

线程有6种状态
  • 初始(NEW):新创建了一个线程对象,但还没有调用start()方法。
  • 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。
  • 线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。
  • 阻塞(BLOCKED):表示线程阻塞于锁。注意和进程的区别,进程是IO阻塞
  • 等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。
  • 超时等待(TIMED_WAITING):该状态不同于WAITING,它可以在指定的时间后自行返回。
  • 终止(TERMINATED):表示该线程已经执行完毕。

在这里插入图片描述
创建:一个新的线程被创建,等待该线程被调用执行;

就绪:时间片已用完,此线程被强制暂停,等待下一个属于它的时间片到来;

运行:此线程正在执行,正在占用时间片;

阻塞:也叫等待状态,等待某一事件(如IO或另一个线程)执行完;

退出:一个线程完成任务或者其他终止条件发生,该线程终止进入退出状态,退出状态释放该线程所分配的资源。

三、同步

所谓同步就是多个操作在同一时间段内只能有一个线程进行,其他线程需要等待当前线程执行完成后才可以执行。

四、死锁

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

死锁产生的4个必要条件
  1. 互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。
  2. 请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
  3. 不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
  4. 环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。

解决方法

死锁预防

可以通过设置某些限制条件,去破坏产生死锁的四个必要条件中的一个或者几个,来预防发生死锁。

  • 有序资源分配
  • 银行家算法

银行家算法是Dijkstra E.W 于1968年提出的,它以银行借贷系统的分配策略为基础,判断并保证系统的安全运行。

死锁检测与解决
  1. 先检测
    可通过系统所设置的检测机构,及时地检测出死锁的发生,并精确地确定与死锁有关的进程和资源
  2. 后解决
    撤销或挂起一些进程,以便回收一些资源,再将这些资源分配给已处于阻塞状态的进程,使之转为就绪状态,以继续运行

同步与死锁

多个线程之间可以共同操作同一资源。
实现的机制可以使用同步代码块或同步方法解决,要使用一个关键字:synchronized
利用同步操作,可以保证数据的合法性,但是所带来的问题是:代码执行速度变慢。
所谓同步就是指一个线程等待另外一个线程执行完毕的过程,它需要一个等待过程。而如果两个线程互相等待各自完成,互相等待的操作即为死锁。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值