操作系统概念学习笔记 12 进程同步(二)管程

简介:

操作系统概念学习笔记 12

进程同步(二)


管程

基本的、高级的同步构造,即管程(monitor)类型。

使用:

管程类型提供了一组由程序员定义的、在管程内互斥的操作。管程类型的表示包括一组变量的声明(这些变量的值定义了一个类型实例的状态)和对这些变量操作的子程序和函数的实现。管程的类型表示不能直接为各个进程所使用。因此,在管程内定义的子程序只能访问位于管程内那些局部声明的变量和形式参数。类似的,管程的局部变量能被局部子程序访问。

管程结构确保一次只有一个进程能在管程内活动。不需要显示的编写同步代码。而对于特定同步方案,需要额外的同步机制,这些由条件(condition)结构来提供。

condition x,y;  
x.wait();  
x.signal();

管程的语法:

monitor monitor name{

  //shared variable declarations

  procedure P1(…){

…

}

procedure P2(…){

…

}procedure Pn(…){

…

}

initialization code(…){

…

}

}

哲学家进餐问题的管程解法

这个解决方案要求哲学家在两只筷子都可以使用时才会拿起筷子。

为此,引入如下数据结构:

enum {THINKING, HUNGRY, EATTING} state[5];

加入条件,哲学家i只有在其两个邻居不再进餐时才能将变量state[i]设置为eating:

(state[(i+4)%5]!=eating)和(state[i+1]%5!=eating)

哲学家i必须按以下顺序来调用操作

dp.pickup(i)

...

eat

...

dp.putdown(i)

基于信号量的管程实现

基于信号量的哲学家进餐问题的管程解法:每个管程都有一个信号量mutex(初始化为1),进程在进入管程之前,必须执行wait(mutex),在离开管程后必须执行signal(mutex)。

monitor dp{

  enum{THINKING,HUNGRY,EATING}state[5];

  condition self[5];



  void pickup(int i){

 state[i]=HUNGRY;

 test(i);

  if(state[i]!=EATING)

    self[i].wait();

}



void putdown(int i){

  state[i]=THINKING;

  test((i+4)%5);

  test((i+1)%5);

}



void test(int i){

  if((state[(i+4)%5]!=EATING)&&(state[i]==HUNGRY)&&(state[(i+1)%5]!=EATING)){

    state[i]=EATING;

    self[i].signal();

}

}



initialization_code(){

  for(int i=0;i<5;i++)

    state[i]=THINKING;

}

}

条件变量的实现:对于每个条件变量x,引入信号量x_sem和整数变量x_count,两者均初始化为0。由于信号进程必须等待,引入另一个信号量next以供信号进程挂起自己,next_count以对挂起在next上的进程进行计数。

x.wait()的实现:

x_count++;

if(next_count > 0)

  signal(next);

else

  signal(mutex);

wait(x_sem);

x_count--;

x.signal()的实现:

if(x_count>0){

  next_count++;

  signal(x_sem);

  wait(next);

  next_count--;

}

管程内的进程重启

等待最长的进程先重新运行。也可以使用条件等待构造。

x.wait(c);其中c表示优先值(priority number),会与悬挂进程的名称一起存储。

使用管程来管理资源时,为确保系统的正确,有两个条件是必须检查的:

第一,用户进程必须总是按正确顺序来对管程进行调用;

第二,必须确保一个不合作的进程不能简单地忽略由管程所提供的互斥关口,以及在不遵守协议的情况下直接访问共享资源。

目录
相关文章
|
6天前
|
Python
多进程同步之文件锁
【10月更文挑战第16天】文件锁是一种常用的多进程同步机制,它可以用于确保多个进程在访问共享资源时的互斥性。在使用文件锁时,需要注意锁的粒度、释放、竞争和性能等问题。通过合理使用文件锁,可以提高多进程程序的正确性和性能
|
6天前
|
算法 调度
探索操作系统的心脏:内核与进程管理
【10月更文挑战第25天】在数字世界的复杂迷宫中,操作系统扮演着关键角色,如同人体中的心脏,维持着整个系统的生命力。本文将深入浅出地剖析操作系统的核心组件——内核,以及它如何通过进程管理来协调资源的分配和使用。我们将从内核的概念出发,探讨它在操作系统中的地位和作用,进而深入了解进程管理的机制,包括进程调度、状态转换和同步。此外,文章还将展示一些简单的代码示例,帮助读者更好地理解这些抽象概念。让我们一起跟随这篇文章,揭开操作系统神秘的面纱,理解它如何支撑起我们日常的数字生活。
|
2月前
|
存储 消息中间件 资源调度
「offer来了」进程线程有啥关系?10个知识点带你巩固操作系统基础知识
该文章总结了操作系统基础知识中的十个关键知识点,涵盖了进程与线程的概念及区别、进程间通信方式、线程同步机制、死锁现象及其预防方法、进程状态等内容,并通过具体实例帮助理解这些概念。
「offer来了」进程线程有啥关系?10个知识点带你巩固操作系统基础知识
|
2月前
|
算法 调度 Python
探索操作系统的内核——一个简单的进程调度示例
【9月更文挑战第17天】在这篇文章中,我们将深入探讨操作系统的核心组件之一——进程调度。通过一个简化版的代码示例,我们将了解进程调度的基本概念、目的和实现方式。无论你是初学者还是有一定基础的学习者,这篇文章都将帮助你更好地理解操作系统中进程调度的原理和实践。
|
3月前
|
调度 虚拟化 容器
探索操作系统的心脏:内核与进程管理
【8月更文挑战第28天】在数字世界的复杂迷宫中,操作系统扮演着关键角色。它如同一座桥梁,连接硬件与软件,确保一切顺畅运行。本文将深入剖析操作系统的核心——内核和进程管理,揭示它们如何协同工作,保障系统的稳定与高效。通过简化的比喻,我们将一探究竟,了解操作系统背后的神秘面纱。
|
3月前
|
算法 安全 调度
揭秘操作系统的心脏:内核与进程管理
【8月更文挑战第27天】在数字世界的庞大机器中,操作系统扮演着至关重要的角色。本文将深入探讨操作系统的核心组件之一——内核,以及它是如何高效地管理和调度进程的。通过浅显易懂的语言和生动的比喻,我们将一起探索这一技术领域的奥秘,并了解其对整个计算生态的影响。无论你是技术新手还是资深爱好者,这篇文章都将为你打开一扇了解操作系统深层工作机制的大门。
|
3月前
|
存储 算法 调度
操作系统的心脏:内核与进程管理
【8月更文挑战第22天】本文将带你深入探索操作系统的核心——内核,以及它如何通过进程管理来维护系统的稳定运行。我们将从内核的基本概念出发,逐步揭示它在操作系统中的角色和功能,并探讨进程管理的重要性及其对系统性能的影响。文章将用通俗易懂的语言,深入浅出地分析内核与进程管理的相互作用,为你呈现一个清晰、条理化的操作系统内部世界。
|
3月前
|
算法 调度 UED
操作系统的心脏:内核与进程管理
在数字世界的宏伟建筑中,操作系统是那支撑起一切软件运行的基石。本文将深入浅出地探讨操作系统的核心—内核,以及它如何通过进程管理来协调计算机资源的使用。我们将从内核的定义和功能出发,逐步深入到进程的生命周期,以及调度算法的重要性,最终揭示这些机制如何影响我们日常使用的电子设备性能。
42 2
|
3月前
|
安全
操作系统中的同步和监视器经典问题
【8月更文挑战第23天】
30 0
|
3月前
|
算法 数据处理 调度
操作系统的心脏:内核与进程管理
【8月更文挑战第21天】 本文以浅显的语言和生动的比喻,探索操作系统内核的奥秘和进程管理的机制。我们将从内核的角色出发,了解它如何协调计算机硬件与软件的交互,并深入进程的世界,揭示它们是如何被创建、调度和同步的。文章通过日常生活中的比喻帮助读者构建对这一复杂主题的直观理解,同时提供实用的知识,让每位用户都能更好地理解自己的电脑是如何运作的。
36 0