进程与线程

进程与线程


进程是操作系统的核心概念,是对正在运行程序的一个抽象。

1 进程

1.1 进程模型

进程(process)就是一个正在执行的程序的实例,包括程序计数器、寄存器和变量的当前值。从概念上说,每个进程拥有它自己的虚拟CPU,而真正的CPU在各进程间来回切换。

1.2 进程的创建

4种主要事件会导致进程的创建:

  • 系统初始化
  • 正在运行的程序执行了创建进程的系统调用
  • 用户请求创建一个新进程
  • 一个批处理作业的初始化

操作系统初始化时会创建若干个进程,有些是前台进程,有些是后台进程,这些进程与特定用户没有关系,但具有某些专门的功能,称为守护进程(daemon)。

进程创建后,父进程和子进程有各自不同的地址空间。不可写的内存区是共享的,若要子进程共享父进程的所有内存,通常使用写时复制(copy-on–write)共享,即两者之一想要修改部分内存,则这块内存首先被复制,以确保修改发生在私有内存区域。可写的内存是不可以共享的

1.3 进程的终止

  • 正常退出(自愿)
  • 出错退出(自愿)
  • 严重错误(非自愿)
  • 被其他进程杀死(非自愿)。

1.4 进程的层次结构

进程只有一个父进程,但可以有多个子进程。在UNIX中,进程和它的所有子进程以及后裔共同组成一个进程组。所有进程都属于以init为根的一棵树。在Windows中没有进程层次的概念,所有进程地位相同。

1.5 进程的状态

运行态:该时刻进程实际占用CPU。

就绪态:可运行,但因其他进程正在运行而暂时停止。

阻塞态:除非某种外部事件发生,否则进程不能运行。

进程的状态间转换有四种可能:

  • 进程因为等待输入而由运行态进入阻塞态
  • 当出现有效输入,进程由阻塞态进入就绪态
  • 当调度程序选择此进程,由就绪态进入运行态
  • 当调度程序选择另一进程,由运行态进入就绪态

1.6 进程的实现

操作系统维护着一张进程表(一个结构数组),每个进程占一个进程表项(或者称为进程控制块),该表项包括程序计数器、堆栈指针、内存分配状况、所打开文件的状态、账号和调度信息及其他进程状态转换的必要信息,以保证该进程随后能再次启动。

中断发生后操作系统底层的工作步骤:

  • 硬件压入堆栈程序计数器。
  • 硬件从中断向量装入新的程序计数器。
  • 汇编语言过程保护寄存器值。
  • 汇编语言过程设置新的堆栈。
  • C中断服务例程运行。
  • 调度程序决定下一个将运行的进程。
  • C过程返回至汇编代码。
  • 汇编语言过程开始新的当前进程。

2 线程

线程(thread)是操作系统能够进行运算调度的最小单元,被包含在进程之中。

2.1 线程的使用

使用线程的必要性:

  • 在进程中同时发生着多种活动,其中某些活动随着时间退役会被阻塞,使用多线程可将其分解为可以准并行运行的多个顺序线程。
  • 线程比进程更轻量级,更容易创建,也更容易撤销。多个线程可以共享公共内存,线程之间是没有保护的,这是进程做不到的。
  • 若存在大量计算和I/O处理,拥有多个线程允许这些活动彼此重叠进行,从而加快应用程序的执行速度。
  • 在多CPU系统中,多线程是有益的,真正的并行有了实现的可能。

2.2 线程模型

与进程一样,线程可以处于若干种状态的任何一个:运行、阻塞、就绪或终止。每个线程有自己的堆栈,所有进程都是平等的。线程通常是有益的,但也让程序设计变得复杂。

2.3 在用户空间中实现线程

实现线程包由两种主要方法:在用户空间中和在内核中。

把整个线程包放在用户空间中,内核对线程包一无所知。优点是用户级线程包可以在不支持线程的操作系统上实现。在用户空间管理线程时,每个进程需要有专用的线程表(thread table),用来跟踪该进程中的线程。用户级线程还允许每个进程有自己的调度算法。

2.4 在内核中实现线程

内核中有用来记录系统中所有线程的线程表,当某个线程希望创建一个新线程或撤销一个已有线程时,它进行一个系统调用,这个系统调用通过对线程表的更新完成线程创建或撤销工作。

2.5 弹出式线程

一个消息的到达导致系统创建一个处理该消息的线程,这种线程称为弹出式线程

3 进程间通信

进程间通信(Inter Process Communication, IPC)有三个问题:一个进程如何把信息传递给另一个;确保多个进程在关键活动中不会交叉;正确的顺序。这些问题同样适用于线程。

3.1 竞争条件

两个或多个进程读写某些共享数据,最后的结果取决于进程运行的精确时序,称为竞争条件(race condition)。

3.2 临界区

避免竞争条件需要的是互斥(mutual exclusion),即以某种手段确保当一个进程在使用一个共享变量或文件时,其他进程不能做同样的操作。把对共享内存进行访问的程序片段称作临界区(critical section),若能适当安排,使两个进程不可能同时处于临界区,就能避免竞争条件。

保证使用共享数据的并发进程能够正确并高效地进行需满足4个条件:

  • 任何两个进程不能同时处于其临界区。
  • 不应对CPU的速度和数量做任何假设。
  • 临界区外运行的进程不得阻塞其他进程。
  • 不得使进程无限期等待进入临界区。

3.3 忙等待的互斥

3.4 睡眠与唤醒

生产者-消费者问题:也叫有界缓冲区问题。两个进程共享一个公共的固定大小的缓冲区,其中一个是生产者,将信息放入缓冲区,另一个是消费者,从缓冲区中取出信息。

3.5 信号量

使用一个整型变量来累计唤醒次数,称作信号量(semaphore),一个信号量的取值可以为0(没有保存下来的唤醒操作)或者为正值(有一个或多个唤醒操作)。对信号量的操作必须二维单一的、不可分割的原子操作,原子性对于解决同步问题和避免竞争条件是绝对必要的。原子操作是指一组相关联的操作要么都不间断地执行,要么都不执行。

3.6 互斥量

若不需要信号量的计数能力,可使用信号量的简化版本,称为互斥量(mutex)。互斥量仅适用于管理共享资源或一小段代码,在线程中非常有用。

互斥量是一个可以处于两态之一的变量:解锁和加锁。

3.7 管程

3.8 消息传递

3.9 屏障

3.6 互斥量

若不需要信号量的计数能力,可使用信号量的简化版本,称为互斥量(mutex)。互斥量仅适用于管理共享资源或一小段代码,在线程中非常有用。

互斥量是一个可以处于两态之一的变量:解锁和加锁。

3.7 管程

3.8 消息传递

3.9 屏障

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值