Modern Operating Systems(Ⅰ)——2014.12.15
进程
进程模型
进程就是一个正在执行的程序的实例
值得注意的是,若一个程序运行了两遍,则算作两个进程
创建进程
在通用系统中,有四种主要事件导致进程的创建
①系统的初始化
②执行了 正在运行的进程 所调用的 进城创建系统调用
③用户请求创建一个新进程
④一个批处理作业的初始化
进程的状态
运行态(该时刻进程实际占用CPU)
就绪态(可运行,但因为其他进程正在运行而暂时停止)
阻塞态(除非某种外部事件发生,否则进程不能运行)
在Operating Systems Concept中还提到了new,terminated两种状态
※进程的实现(PCB)
PCB(进程控制块) | |
Process state | running,waiting |
Program counter | 指示该进程将要执行的下一条指令的地址 |
CPU registers | 累加器(accumulators)、索引寄存器(index registers)、栈指针(stack pointers)、通用寄存器(general-purpose registers)等等 |
CPU scheduling information
|
进程优先级(priority)、调度队列指针及其他调度参数 |
Memory-management information
|
base and limit registers的值, 页表或段表(page tables, or segment)
|
Accounting information
|
CPU used, clock time elapsed since start, time limits
|
I/O status information
|
the list of I/O devices allocated to this process, a list of open files, and so on
|
线程
线程的使用
为什么在进程之下使用线程?
因为有了进程的抽象概念 我们得以不必考虑中断 定时器 上下文切换 类似的 正因为有了线程的抽象概念 我们得以加入了一个新的元素 并行实体共享同一个地址空间和所有可用数据的能力 而这是多进程模型(它们具有不同地址空间)所无法表达的
经典的线程模型
理解进程的一个角度是 用某种方法把相关的资源集中在一起 那么 线程就是在CPU上被调度执行的实体
多个线程共享一个地址空间和其他资源 而 多个进程共享物理内存 磁盘 打印机 和其他资源
一个线程可以读 写 甚至清除另一个线程的堆栈 线程之间是没有保护的 之所以这样是因为不可能 没必要
每个线程自己的内容:程序计数器 寄存器 堆栈 状态(跟进程相同)
在用户空间中实现线程
把整个线程包放在用户空间中 内核对线程包一无所知(从内核的角度看,就是按正常的方式管理,即单线程进程)
每个进程有其专用的线程表 记录线程的属性(程序计数器 堆栈指针 寄存器 状态)
优点:调度快捷 效率高(都是本地过程) 不需要陷阱 不需要上下文切换 不需要对内存高速缓存进行刷新
每个进程有自己的调度算法
缺点:如何实现阻塞系统调用
如果一个线程开始运行 那么该进程中的其他线程就不能运行 (在用户空间实现线程时)
在内核中实现线程
内核中有用来记录系统中所有线程的线程表
进程间通信
竞争条件
两个或多个进程读写某些共享数据,而最后的结果取决于进程运行的精确时序
临界区
正确高效的避免竞争条件需要满足:
任何两个进程不能同时处于其临界区
不应对CPU的速度和数量做任何的假设
临界区外运行的进程不得阻塞其他进程
不得使进程无限期等待进入临界区
忙等待的互斥
互斥:以某种手段保证当一个进程在使用一个共享变量或文件时,其他进程不能做同样的操作
屏蔽中断
每个进程在刚刚进入临界区以后立即屏蔽所有中断,并在就要离开前再打开中断
锁变量
设想有一个锁变量,初始值为0。当一个进程想进入临界区,首先测试这把锁,若值为0,进入,并把值设为1;若为1,则该进程将等待其变为0
缺陷:假设一个进程读出锁变量的值并发现它为0,而恰好在它将其值设置为1之前,另一个程序被调度运行(因为CPU严格按照时钟中断执行顺序进程),将其锁变量置为1,当另一个进程再次运行时同样将锁变量置为1,但此时有两个进程进入临界区之内
严格轮换法
- while(TRUE){
- while(turn != )
- critical_region();
- turn = ;
- noncriti_region();
- }
- while(TRUE){
- while(turn != )
- critical_region();
- turn = ;
- noncriti_region();
- }
turn初始值为0,用于记录轮到哪个进程进入临界区,并检查或更新共享内存。
开始时,进程0检查turn,为0,进入临界区,进程1也发现为0,但进程1的进入条件是turn = 1,于是在一个等待循环中不停地测试
缺陷:试想这样一个情况,进程0离开临界区时,将turn值设为1,以便进程1进入,进程1离开后,将turn设置为0;此时两个进程都处于临界区之外,turn值又被设置为0.现在进程0完成了整个循环,它退出临界区,将turn值设置为1。此时turn值为1,两个进程都在临界区之外进行;突然,进程0完成了非临界区的操作并返回到循环开始,但是这时它并不能进入临界区,进程0只能只能继续while循环,直到进程1把turn的值改为0,可见,在一个进程比另一个进程慢了很多的情况下,轮流进入临界区并不是一个好方法
Peterson解法
睡眠与唤醒
生产者-消费者问题
信号量
管程
管程是一个由过程、变量以及数据结构等组成的集合,是一个特殊的模块或者软件包。
管程有一个很重要的特性,即任意时刻管程中只能有一个活跃进程,典型的处理方法是:当一个进程调用管程时,该过程前几条指令将检查在管程中是否有其他的活跃进程,如果有,该进程挂起,直到另一个进程离开管程将其唤醒。
管程也提供了实现互斥的途径:条件变量以及两个相关的操作,wait(),signal() 当一个管程过程发现它无法继续运行时(例如,生产者发现缓存区满),它会在某个条件变量上(如full)执行wait操作。该操作导致调用进程自身阻塞,并且还将另一个之前等在管程之外的进程调入管程。而另一个进程,可以通过对其伙伴正在等待的一个条件变量执行signal从而唤醒伙伴进程
wait,signal与sleep,wake的区别在于,后者不存在严重的竞争条件
调度
何时调度?
创建一个新的进程后
在一个进程退出时
当一个进程阻塞在I/O和信号量上或由于其他原因阻塞时
一个I/O发生中断
调度算法
哲学家进餐问题
读者-写者问题
Modern Operating Systems(Ⅰ)——2014.12.15的更多相关文章
- 串口通信编程向导 Serial Programming Guide for POSIX Operating Systems
https://www.cmrr.umn.edu/~strupp/serial.html#CONTENTS Introduction Chapter 1, Basics of Serial Commu ...
- Method of address space layout randomization for windows operating systems
A system and method for address space layout randomization ("ASLR") for a Windows operatin ...
- 《modern operating system》 chapter 5 Input and output 注意事项
Input / Output It should also provide an interface between the devices and the rest of the system th ...
- [原创] 【2014.12.02更新网盘链接】基于EasySysprep4.1的 Windows 7 x86/x64 『视频』封装
[原创] [2014.12.02更新网盘链接]基于EasySysprep4.1的 Windows 7 x86/x64 『视频』封装 joinlidong 发表于 2014-11-29 14:25:50 ...
- [No00003D]操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock
操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock 可以操刀了—从纸上到实际 从Linux 0.11 那里学点东西… 读磁盘 ...
- [No00003C]操作系统Operating Systems进程同步与信号量Processes Synchronization and Semaphore
操作系统Operating Systems进程同步与信号量Processes Synchronization and Semaphore 进程合作:多进程共同完成一个任务 从纸上到实际:生产者− − ...
- [No00003A]操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads
开始核心级线程 内核级线程对多核的支持怎么样? 和用户级相比,核心级线程有什么不同? ThreadCreate 是系统调用,内核管理TCB ,内核负责切换线程 如何让切换成型? − − 内核栈,TCB ...
- 大型网站演化(转载 http://homeway.me/2014/12/10/think-about-distributed-clusters/)
0x01.大型网站演化 简单说,分布式是以缩短单个任务的执行时间来提升效率的,而集群则是通过提高单位时间内执行的任务数来提升效率. 集群主要分为:高可用集群(High Availability Clu ...
- LAMP开发之环境搭建(2014.12.7在ubuntu下)
Ubuntu下搭建LAMP环境 前言:学习PHP脚本编程语言之前,必须先搭建并熟悉开发环境,开发环境有很多种,例如LAMP.WAMP.MAMP等.这里我搭建的是LAMP环境,即Linux.Apache ...
随机推荐
- a new blog from MarsEdit
终于在网上找到了一款mac 下的blog写作和发布工具了. 先测试一下.
- 优先级反转实验,使用信号量实现【RT-Thread学习笔记 5】
RTOS中很经典的问题.就是在使用共享资源的时候,优先级低的进程在优先级高的进程之前执行的问题.这里模拟这种情况. 下面的实验模拟了优先级反转的情况: 先定义三个线程: //优先级反转实验 rt_se ...
- Python第八天
Python面向对象进阶 一.静态方法 通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法,什么是静态方法呢?其实不难理解,普通的方法,可以在实例化后直接调用,并且在方法里可以通过 ...
- Eclipse IDE for Java EE Developers 与 Eclipse Classic(Eclipse Standard)区别
Eclipse下载官网:http://www.eclipse.org/downloads/ 版本: 1.Eclipse classic(Eclipse Standard):Eclipse的标准版; 2 ...
- android-23 View.java - dispatchTouchEvent源码
public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource { /** * ...
- C#实现堆栈
堆栈(Stack)是一种特殊的线性表,是一种操作只允许在尾端进行插入或删除等操作的线性表.表尾允许进行插入删除操作,称为栈顶(Top),另一端是固定的,称为栈底(Bottom).栈的操作使按照先进后出 ...
- yii-basic-app-2.0.5/basic/config/web.php
<?php $params = require(__DIR__ . '/params.php'); $config = [ 'id' => 'basic', 'basePath' => ...
- Error 2103 “Unhandled Error in Silverlight Application“ 解决办法
当调试SilverLight项目时,如果出现如下错误: 当调试页面时出现如下错误: 解决办法为:打开工程属性,在Startup object:处选择相应的启动应用程序.
- Java的常用对象①②
Java的常用对象① Java的常用对象有很多,这里只对lang包中常用的Object,Date(Calendar,DateFormat,Math),System,Runtime进行介绍.㈠Objec ...
- Norflash控制器的Verilog建模之二(仿真)
前言:经过几天修改,norflash控制器基本已经完成,通过仿真.完整的norflash包含2个模块:直接操作硬件的norflash_ctrl.v与控制ctrl模块的驱动norflash_driver ...