操作系统:进程与线程

1. 进程概念

未配置OS的系统中,程序是顺序执行的;在多道程序环境下,允许多个程序并发执行。

1.1 程序顺序执行的特征
  1. 顺序性:处理机操作严格按照所规定的顺序执行。即:本操作结束之后才可以进行下一个操作。
  2. 封闭性:程序在封闭环境下执行。即:程序运行时独占全机资源,资源的状态只有本程序才能改变,程序一旦执行,其结果不受外界因素干扰
  3. 可再现性:只要程序执行时的环境和初始条件相同,当程序重复执行时,都能的到相同的结果。

正是由于程序顺序执行的这些特点,给程序猿debug带来了极大的方便

1.2 程序并发执行的特征
  1. 间断性:程序在并发执行的过程中,由于共享资源以及为完成同一任务而合作,致使这些并发的程序形成了相互制约的关系。例如:B的计算必须要使用A的输出,那么在A未输出时候B必须等待。即:执行-暂停-执行这种“走走停停”的活动规律。

  2. 失去封闭性:由于程序并发执行时资源共享,即:该资源状态可以被多个程序更改,致使程序失去封闭性。例如:打印机被一个程序占用时,另外的程序必须等待。

  3. 不可再现性:程序并发执行时,由于失去了封闭性,也导致其失去可再现性。例如:A程序与B程序共享变量x,A程序每执行一次x+1,B程序每执行一次先Print(x),后将x置0。若A,B以不同速度运行,则可能出现以下情况:

    1. x = x + 1在Print(x)与x = 0 之前
    2. x = x + 1在Print(x)与x = 0之间
    3. x = x + 1在Print(x)与x = 0 之后

    不同的情况得到的结果各不相同。

1.3 进程的特征

多道程序环境下,由于程序的并发执行会使其失去封闭性与可再现性。为使程序能够并发执行,且对并发执行的程序加以描述与控制,故:引入“进程的概念”。

  1. 结构特征:进程控制块,即PCB;由程序段,相关数据段和PCB三部分构成了进程实体。早期Unix版本中,这三部分总称为“进程映像”。例:所谓创建进程,实质上是创建进程实体中的PCB,撤销进程,实质上是撤销进程的PCB。
  2. 动态性:进程的实质是进程实体的一次执行过程,因此,动态性是进程的最基本特征—“由创建而产生,由调度而执行,由撤销而消亡”。进程具有一定的生命周期。程序则只是一组有序指令的集合,是静态的
  3. 并发行:多个进程实体同存在于内存中,且能在一段时间内同时运行。并发性室进程的重要特征,同时也是成为OS的重要特征。
  4. 独立性:进程实体是一个能独立运行,独立分配资源和独立接受调度的基本单位。
  5. 异步性:各进程以各自独立的,不可预知的速度运行。

进程的定义

  1. 进程是程序的一次执行。
  2. 进程是一个程序及其数据在处理机上顺序执行时所发生的活动。
  3. 进程时程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。
1.4 进程的状态

三种基本状态

  1. 执行状态:进程已获得CPU,程序正在执行。
  2. 就绪状态:进程已分配到除CPU以外的所有必要资源后,只要获得CPU,便可以立即执行。那么此时的状态称为就绪状态。处于就绪状态的进程通常将他们排成一个队列,称为就绪队列。
  3. 阻塞状态:正在执行的进程由于发生某事件暂时无法继续执行,便放弃处理机而处于暂停状态,这种暂停状态称为阻塞状态。通常也将由于不同原因造成阻塞的进程排成一个队列,称为阻塞队列。

挂起状态

  1. 挂起状态的原因
    1. 父进程请求。
    2. 负荷调节的需要。实时系统中的工作负荷严重,可能影响到对实时任务的控制时,把不重要的进程挂起,保证系统正常运行。
    3. 操作系统的需要。
    4. 终端用户的请求。
  2. 进程状态的转换
    1. 活动就绪—>静止就绪。进程处于未被挂起的就绪状态Readya时,当用挂起原语Suspend将该进程挂起后,该进程便转换为静止就绪状态Readys,此状态的进程不再被调度执行。
    2. 活动阻塞—>静止阻塞。进程处于未被挂起的阻塞状态Blockeda时,当用Suspend将该进程挂起后,该进程转换为静止阻塞状态Blockeds,此状态的进程所期待的时间出现后,状态转变为静止就绪状态。
    3. 静止就绪—>活动就绪。处于Readys状态的进程,用激活原语Active激活后,进程转变为Readya状态
    4. 静止阻塞—>活动阻塞。处于Blockeds状态的进程,用Active激活后,进程转换为Blockeda状态。

创建状态和终止状态

  1. 创建状态。创建进程分为两个步骤:1️⃣为进程创建一个PCB,填写必要信息;2️⃣把该进程转为就绪状态并插入就绪队列。一般而言,进程已拥有PCB,但此时还未进入主存,即创建过程还未完成,不能进行调度运行。此时的状态为创建状态。
  2. 终止状态。终止进程也分为两个步骤:1️⃣等待操作系统进行处理;2️⃣将PCB清0,并将PCB空间返还系统。当一个系统到达了自然结束点或是出现了无法克服的错误,将进入终止状态。进入终止状态的进程不能再被执行,但在操作系统这种仍然保留一个记录(状态码,记时统计数据)供其他进程收集,收集结束和,删除该进程。
1.5 进程控制块PCB

进程控制块的作用

  1. 为了描述和控制进程的运行,系统为每个进程定义了一个数据结构—进程控制块PCB。它是进程实体的一部分,是操作系统中最重要的记录型数据结构。
  2. 进程控制块作用是使一个在多道程序环境下不能独立运行的程序(含数据),成为一个能独立运行的基本单位,一个能与其他进程并发执行的进程。
  3. PCB中记录了操作系统所需要的,用于描述进程的当前情况以及控制进程运行的全部信息;OS也可以通过PCB来对并发的进程进行控制和管理。

进程控制块的信息

  1. 进程标示符
    1. 进程标示符用于唯一地表示一个进程
    2. 内部标识符。所有操作系统中,都为每一个进程赋予一个唯一的数字标识符,通常是一个进程的序号。设置内部标识符主要为了方便系统使用
    3. 外部标识符。由创建者提供,通常是由字母,数字组成,往往由用户在访问该进程时使用。
  2. 处理机状态
    1. 处理机状态信息主要由处理机的各种寄存器中的内容组成。
    2. 处理机运行时,信息放在寄存器中,当处理机被中断时,所有信息必须保存在PCB中,以便在该进程重新执行时,能够从断点继续执行
    3. 通用寄存器:用户程序可以访问,暂存信息
    4. 指令计数器:存放了要访问下一条指令的地址
    5. 程序状态字PSW:含有状态信息,如:条件码,执行方式,中断屏蔽标志
    6. 用户栈指针:用于存放过程和系统调用参数及调用地址,栈指针指向该栈的栈顶
  3. 进程调度信息
    1. 进程状态。指明进程的当前状态,作为进程调度和对换时的依据
    2. 进程优先级。用于描述进程和处理机的优先级别的一个整数,优先级高的进程有限获得处理机
    3. 进程调度所需的其他信息。如,调度所采用的算法
    4. 事件。指进程由执行状态转换为阻塞状态所等待的发生事件。即:阻塞原因
  4. 进程控制信息
    1. 程序和数据的地址。指进程的程序和数据所在的内存或外存地址,以便调度到该进程时,能从PCB中找到其程序和数据
    2. 进程同步和通信机制。实现进程同步和通信必须的机制。如:信号量,消息队列等
    3. 资源清单。除CPU外,进程所需要的全部资源
    4. 链接指针。给出本进程PCB所在队列中的下一个进程的PCB地址

进程控制块的组织方式

  1. 链接方式。把具有同一状态的PCB用其中的链接字连成一个队列。
  2. 索引方式。系统根据所有的进程建立PCB索引表。如:就绪索引表,阻塞索引表

2. 进程控制

进程控制是进程管理中最基本的功能。

进程控制:创建进程,终止进程,状态转换等等

进程控制一般是由OS的内核中的原语来实现的。

原语:由若干条指令组成的,用于完成一定功能的一个过程。是“原子操作”—指一个操作中的所有动作要么全做,要么全不做,是不可分割的。因此,在执行过程中不允许被中断,原子操作在管态下执行,常驻内存。

原语的作用:为了实现进程的通信和控制。

2.1 进程创建

子进程可以拥有父进程所拥有的资源,撤销父进程时,也必须同时撤销其所有子进程

  1. 申请空白PCB。为新进程申请获得唯一的数字标识符,并从PCB集合中索取一个空白PCB
  2. 为新进程分配资源。为新进程分配必要的内存空间
  3. 初始化进程控制块。PCB的初始化包括
    1. 初始化标示信息。将系统分配的标示符和父进程标示符填入PCB。
    2. 初始化处理机状态信息。程序计数器只想程序的入口地址,使栈指针指向栈顶。
    3. 初始化处理机控制信息。将进程的状态设置为就绪状态或静止就绪状态;优先级通常设置为最低优先级。
  4. 将新进程插入就绪队列
2.2 进程终止
  1. 根据被终止进程的标示符。从PCB集合中检索出该进程的PCB,从中读出该进程的状态。
  2. 若被终止进程正处于执行状态,则立即终止该进程的执行,并置调度标志为真,用于指示该进程被终止后应该重新进行调度
  3. 若该进程还有子孙进程,应将其所有子孙进程全部终止,以防成为不可控进程
  4. 将被终止进程拥有的所有资源,归还给父进程或系统
  5. 将被终止进程PCB从所在队列中移除,等待其他程序来搜集信息,搜集完毕后删除。
2.3 进程阻塞与唤醒

进程阻塞

  1. 进程的阻塞是一种主动行为
  2. 正在执行的进程,由于某事件无法继续执行,于是调用阻塞原语block将自己阻塞
  3. 进入block过程后,由于此时该进程还处于执行状态,所以应先立即停止执行,把进程控制块的现行状态由“执行”改为“阻塞”,并将PCB插入阻塞队列。

进程唤醒

  1. 当阻塞进程所期待的时间出现时,由有关进程调用唤醒原语wakeup(),并将该事件的进程唤醒。
  2. 首先把被阻塞进程从阻塞队列中移出,将其PCB的现行状态由“阻塞”改为“就绪”,将其插入到就绪队列中

block原语语wakeup原语是一对作用刚好相反的原语。

2.4 进程的挂起与激活

进程挂起

  1. 系统利用suspend()原语将制定进程或处于阻塞状态的进程挂起
  2. 检查被挂起进程的状态,若处于活动就绪态,便将其转换为静止就绪态;活动阻塞态,则将其转换为静止阻塞态
  3. 为了方便用户或父进程考查该进程的运行情况而把该进程的PCB复制到某指定的内存区域。若被挂起的进程正在执行,则重新调度。

进程激活

  1. 系统利用active()原语将制定进程激活
  2. 激活原语先将进程从外存换入内存。检查该进程的现行状态,若静止就绪,将其改为活动就绪;若为静止阻塞将其改为活动阻塞
  3. 假如采用的是抢占式调度策略,每当有新进程进入就绪队列时,应检查是否进行重新调度

3. 进程同步

OS引入进程之后,虽然提高了资源的利用率和系统的吞吐量,但是由于进程的异步性,在他们争用临界资源时会造成系统混乱。

进程同步的主要任务:对多个进程在执行的次序上进行协调,以使并发执行的诸多进程之间能够有效地共享资源和相互合作,从而使程序的执行具有可再现性。

3.1 进程同步概念

进程之间的两种制约关系

  1. 间接相互制约关系。同处于一个系统中的进程,通常都共享着某种系统资源。例如:打印机被A进程占有时,那么此时需要打印机的B进程只能阻塞
  2. 直接相互制约关系。这种制约关系主要源于进程之间的合作。

临界资源。诸如:打印机等许多硬件设备,都属于临界资源,诸进程间采用互斥方式,实现对这种资源的共享。

临界区。对于临界资源,进程必须采用互斥方式进行访问。那么访问临界资源的那段代码称为临界区。

同步机制遵循的规则

  1. 空闲让进。无进程处于临界区时,表明临界资源处于空闲状态,允许请求的进程进入自己的临界区
  2. 忙则等待。当已有进程进入临界区时,表明临界资源正在被访问,其他试图进入临界区的进程必须等待
  3. 有限等待。对要求访问临界资源的进程,应保证在有限时间内进入临界区,以免进入“死等”状态
  4. 让权等待。当进程不能进入临界区时,应立即释放处理机,以免进入“忙等”状态
3.2 信号量机制

信号量机制是一种进程同步的工具。

  1. 整型信号量

最初的整型信号量被定义为一个用于表示资源数目的整型量S,除了初始化之外,仅能通过两个标准的原子操作wait(S)和signal(S)来访问。这两个操作被分别称为P,V操作。P,V操作可以描述为:

wait(S):
	while S <= 0 do no-op
	S:=S-1
signal(S):
	S:=S+1

wait(S)和signal(S)是两个原子操作,执行时不可中断。

wait(S)操作:当资源数目S大于0时,即进程可以获取该资源,随后将该资源数目-1;当资源数目S小于等于0时,表示没有空闲的资源,进程等待不做任何操作,直至有资源被释放

signal(S)操作:每次释放资源后,资源数目+1

  1. 记录型信号量

整型信号量机制中的wait操作,只要信号量S<=0,就会不断进行测试。因此,该机制未遵循“让权等待”准则,而使进程处于“忙等”的状态。

记录型信号量机制是一种不存在“忙等”现象的进程同步机制,采取“让权等待”,但是此时会出现多个进程访问同一临界资源的情况,因此还应该增加一个进程链表指针L,用于链接上述的所有等待进程。

procedure wait(S)
	var S: semaphore
	begin
		S.value:=S.value-1
		if S.value<0 then block(S, L)
	end
procedure signal(S)
	var S: semaphore
	begin
		S.val:=S.value+1
		if S.value<=0 then wakeup(S, L)
	end

记录型信号量机制中,S.value的初值代表系统中的某类资源的数目,又被称为“资源信号量”。

wait操作:意味着进程请求一个单位的该类资源,使系统中可供分配的该类资源数目-1;当S.value<0时,表示系统内无可分配的该类资源,因此进程调用block原语进行自我阻塞,放弃处理机,并插入到链表L中。此时S.value的绝对值表示系统内已阻塞进程的数目

signal操作:表示进程释放了一个该类资源,此时系统内可供分配的信号量S.value+1。若S.value<=0时,表示系统内仍有进程被阻塞,故应该调用wakeup原语唤醒链表L中的第一个等待进程。

  1. And型信号量

整型信号量机制与记录型信号量机制是针对各个进程之间只共享一个临界资源而言的。那么当一个进程需要获得两个或更多的共享资源后方能执行任务时,需要用到And型信号量机制。

And型信号量思想: 将进程在在运行过程中需要的资源,一次性全部分配给该进程,待进程使用完之后在全部释放。只要有一个资源未被分配给该进程,其他所有可能为之分配的资源都不分配给它。

对于若干个资源的分配采用原子操作的方式:要么全部分配,要么一个也不分配,这样能够避免死锁。

Swait(S1, S2, ..., Sn)
	if Si>=1 and ... Sn>=1 then
		for i:=1 to n do
				Si:=Si-1
		endfor
	else
	place the process in the waiting queue associated with the first Si found with Si<1,and set the program count of this process to the beginning of Swait operation
	endif
Signal(S1, S2, ..., Sn)
	for i:=1 to n do
			Si:=Si+1
	Remove all the process waiting in the queue associated with Si into the ready queue.
	endfor

wait操作:确保进程所需的所有资源都存在,那么将所需的所有资源都分配给该进程。即:所需的所有资源数目-1;否则,不给予分配任何资源

signal操作:释放分配给该进程的所有资源,即:已分配资源的数目+1

  1. 信号量集

在记录型信号量中,wait操作和signal操作仅能对信号量实施+1或者-1,当一次需要N个临界资源时,便要进行N此wait操作,这显然很低效。此外,在某些情况下,当资源数目低于某一下限时,便不予分配。因此,在每次分配之前都需要测试该资源的数目,看其是否大于下限值。

基于以上的要求,可以对“And信号量机制”进行扩展。

下述S为信号量,t为下限值,d为需求值

Swait(S1, S2, ..., Sn, tn, dn)
	if Si>=t1 and ... Sn>=tn then
		for i:=1 to n do
				Si:=Si-di
		endfor
	else
	place the process in the waiting queue associated with the first Si found with Si<1,and set the program count of this process to the beginning of Swait operation
	endif
Signal(S1, S2, ..., Sn, dn)
	for i:=1 to n do
		Si:=Si+di
	Remove all the process waiting in the queue associated with Si into the ready queue.
	endfor

wait操作:每次分配至之前,先去判断所需每类资源的信号量是否大于等于其下限值,若满足条件,则进行分配,每次分配其所需的资源数目di;否则,不予分配

signal操作:每次释放已分配的资源数目di

特殊情况

  1. SWait(S, d, d)。此时信号量集中只有一个信号量,允许它每次申请d个资源,当现有资源数目小于d时,不予分配
  2. SWait(S, 1, 1)。此时信号量集已变为一般的记录型信号量或互斥信号量
  3. SWait(S, 1, 0)。当S>=1时,允许多个进程进入某特定区;当S变为0后,将阻止任何进程进入特定区
3.3 管程机制

管程:定义了一个数据结构和能为并发进程所执行在该数据结构上的一组操作,这组操作能同步进程和改变管程中的数据。管程由以下四部分组成:

  1. 管程的名称
  2. 局部于管程内部的共享数据结构说明
  3. 对该数据结构进行操作的一组过程
  4. 对局部管程内部数据结构的共享数据设置初始值的语句

局部于管程内部的数据结构,仅能被管程内的过程访问,任何管程外的都不能访问它。

局部于管程内部的过程,只能访问管程内部的数据结构。

管程相当于围墙,把共享变量和对它进行操作的若干过程围起来,所有要访问临界资源的进程,都必须通过管程来访问,而管程每次只允许一个进程进入管程,从而实现了进程互斥。

4. 经典进程同步问题

4.1 生产者-消费者问题

利用记录型信号量机制解决

假定生产者与消费者之间的公用缓冲池中,具有n个缓冲区,利用互斥信号量mutex实现诸进程对缓冲池的互斥使用,利用信号量empty和full分别表示缓冲池这种空缓冲区和满缓冲区数量。

Var mutex, empty, full: semaphore:=1, n, 0
	buffer:array[0, ... , n-1] of item
	in, out: integer:=0, 0
	begin
		parbegin
			procedure: begin
				repeat
					producer an item nextp;
					wait(empty);
					wait(mutex);
					buffer(in):=nextp;
					in:=(in+1) mod n;
					signal(mutex);
					signal(full);
					until false;
				end
			consumer: begin
				repeat
				wait(full);
				wait(mutex);
				nextc:=buffer(out);
				out:=(out+1) mod n;
				signal(mutex);
				signal(empty);
				consumer the item in nextc;
				until false
			end
		parend
	end

生产者:若空缓冲区数量为0,则不予任何操作,否则将空缓冲区数量-1,生产者对缓冲池进行操作wait(mutex),将生产的nextp放入缓冲区内buffer(in):=nextp并指针后移in:=(in+1) mod n;结束对缓冲池的使用signal(mutex),增加缓冲池中的满缓冲区数量signal(full)

消费者同理

利用And信号量机制解决生产者-消费者问题

利用Swait(empty, mutex)来代替wait(empty)和wait(mutex);用Ssignal(mutex, full)来代替signal(mutex)和signal(full)等

Var mutex, empty, full: semaphore:=1, n, 0
	buffer:array[0, ... , n-1] of item
	in, out: integer:=0, 0
	begin
		parbegin
			procedure: begin
				repeat
					producer an item nextp;
					Swait(empty, mutex);
					buffer(in):=nextp;
					in:=(in+1) mod n;
					Ssignal(mutex, full);
					until false;
				end
			consumer: begin
				repeat
				Swait(full, mutex);
				nextc:=buffer(out);
				out:=(out+1) mod n;
				Ssignal(mutex, empty);
				consumer the item in nextc;
				until false
			end
		parend
	end

利用管程机制解决生产者-消费者问题

首先建立一个管程PC,其包括

  1. Put(item):生产者将产品放入缓冲池;当缓冲池中产品数>=n时,缓冲池已满,生产者等待
  2. Get(item):消费者从缓冲池中取出产品;当缓冲池中产品数<=0时,缓冲池无产品,消费者等待

4.2 哲学家进餐问题

利用记录型信号量解决哲学家进餐问题

桌子上的筷子都是临界资源,一段时间内只允许一位哲学家使用。实现对筷子的互斥使用,可以使用一个信号量表示一只筷子。

Var chopstick: array[0, ..., 4] of semaphore
	repeat
		wait(chopstick[i]);
		wait(chopstick[(i+1) mod 5])
		eat;
		signal(chopstick[i]);
		signal(chopstick[(i+1) mod 5])
	unti false;

上述表示哲学家每次先去拿他们左边的筷子,成功之后再去拿右边的筷子。

这时会遇到一个问题,五个哲学家同时拿起了他们各自的左边的筷子,此时所有的哲学家都处于等待状态,造成死锁。以下几种可以解决死锁问题:

  1. 最多允许4位哲学家同时去拿筷子
  2. 仅当哲学家左右两个筷子均可用时,才允许他拿起筷子
  3. 规定奇数号哲学家先拿其左边筷子,偶数号哲学家则相反

利用And信号量机制解决哲学家进餐问题

Var chopsiick array of semaphore:=(1,1,1,1,1)
	repeat
		Swait(chopstick[i], chopstick[(i+1) mod 5])
		eat;
		Ssignal(chopstick[i], chopstick[(i+1) mod 5])
	unti false;
4.3 读者-写者问题

允许多个进程读一个共享对象,但是不允许一个写进程和其他读进程同时访问共享变量。

所以,读者-写者问题即为:保证Write进程与其他进程互斥访问共享对象的同步问题

利用记录型信号量解决读者-写者问题

为实现Writer进程与Reader进程在读或写的互斥设置了一个互斥信号量Wmutex;设置变量Readercount表示正在读的进程数目。只要有进程在读共享对象,便不允许Writer进程去写。仅当Readercount值为0时,表示这是第一个读的进程要和写进程互斥,才需要去wai t(wmutex);读完之后若Readercount>0,表示还有进程仍在读,故仅当Readercount=0时,才需要signal(wmutex)

5. 进程通信

进程通信:指进程之间的信息交换。

进程之间的互斥和同步,由于其交换的信息量少而被归为低级通信。

接下来的内容属于高级进程通信—指用户可以直接利用操作系统所提供的一组攻心命令高效地传输大量数据的通信方式。

5.1 进程通信的类型

高级通信机制分为三大类:共享存储器系统,消息传递系统,管道通信系统

  1. 共享存储器系统:相互通信的进程共享某些数据结构或共享存储区,进程之间通过这些空间来通信
    1. 基于共享数据结构的通信方式。此通信方式要求诸多进程公用某些数据结构来实现信息交换
    2. 基于共享存储区的通信方式。在存储器中划出一块共享存储区,诸进程可以通过对共享存储区中的数据进行读或写来进行通信
  2. 消息传递系统
    1. 进程间的数据交换是以格式化的消息为单位的
    2. 分为直接通信方式和间接通信方式
  3. 管道通信
    1. “管道”:用于连接一个读进程和一个写进程以实现他们之间通信的一个共享文件pipe
    2. 当一个进程的、正在对pipe进行执行读/写操作时,另外一个进程必须等待
    3. 当pipe满时,写进程睡眠等待;当pipe空时,读进程睡眠等待
    4. 只有读/写进程确定了对方的存在,才能进行通信
5.2 消息传递通信
  1. 直接通信方式

    1. 发送进程利用OS所提供的命令,直接将消息发送到目标进程。
    2. Send(Receiver, message); Receive(Sender, message)
  2. 间接通信方式

    1. 进程之间的通信需要通过作为共享数据结构的实体。该实体用来暂存信息,该实体通常被称为“信箱”。利用信箱,可实现实时通信,又可以实现非实时通信。
    2. 发送方需要消息发送给信息,接收方从信箱内获取消息

6. 线程

进程作为拥有资源和独立运行的基本单位,所以在进程进行切换时由于需要保留当前进程的CPU环境和设置新选中进程的CPU环境,因而会话费大量的处理机时间。进程作为资源的拥有者,在创建,撤销,切换时必将有着大量的时空开销。

为了使程序能够更好地并发执行并尽可能的减少时空开销,引入了线程。使进程作为拥有资源的基本单位,而线程作为调度和分派的基本单位。

6.1 线程属性
  1. 轻型实体。线程基本不拥有资源
  2. 独立调度和分派的基本单位。线程的切换非常迅速且开销小
  3. 可并发执行
  4. 共享进程资源
6.2 线程间的同步和通信
  1. 互斥锁

互斥锁是一种比较简单的,用于实现线程间对资源互斥访的机制。适用于高频度使用的关键共享数据和程序段。有开锁unlock和关锁lock两种状态。

  1. 条件变量

只使用互斥锁的情况极其容易造成“死锁”现象。

  1. 信号量机制

    1. 私有信号量。当线程需要利用信号量来实现同一进程中各线程之间的同步时,可以创建一私有信号量,其数据结构存放在应用程序的地址空间中。私有信号量属于特定的进程所有,OS不知道信号量的存在;当私有信号量的占用者正常结束或异常结束时,OS无法使它恢复为0,也不能将其传送给下一个请求进程。
    2. 共有信号量。公有信号量是为了实现不同进程间或不同进程中各线程之间的同步而设置的。其数据结构放在受保护的系统存储区内,由OS为其分配空间并进行管理,故称“系统信号量”。在其占有者结束时为释放该公有信号量,OS会自动回收该信号量空间,并通知下一进程
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值