从Java角度理解操作系统概念-第六版

不完全《从Java角度理解操作系统概念-第六版》详细解读

封面5 拷贝.png

作者:老九—技术大黍

产品:查看原文

社交:知乎

公众号:老九学堂(新手有福利)

特别声明:原创不易,未经授权不得转载或抄袭,如需转载可联系笔者授权

前言

在编程界存在一个这样鄙视链:

  • 二进制机器语言鄙视汇编
  • 汇编鄙视C/C++
  • C/C++鄙视Java
  • Java鄙视C#
  • C#鄙视PHP
  • PHP鄙视JavaScript
  • JavaScript鄙视Python
  • Phthon鄙视...

一般C/C++的程序员是真看不上Java程序员的,因为很多非科班出身的Java应用开发程序员是不懂硬件原理和操作系统原理的,当然这个范围不包括我哈。但是,如果Java程序员不懂硬件原理和操作系统原理,却又很不幸运地搞起了大数据和分布式微服应用开发,那么不懂硬件原理和操作系统原理的Java程序员还真干不了这种应用程序的调试、优化工作。

如果只会写Java代码,但是不用去做分布式应用的调试和优化的程序员,他们是不需要掌握硬件原理和操作系统原理的。但是,现在应用一个Java全栈程序员岗位,或者应用应聘一个Java后台开发岗位时,一定会被面试官问及:有MySQL数据库的优化经验吗?有JVM优化经验吗?等等包括有Tomcat优化经验吗?这样的问题!

如果我们只是为了面试,我觉得大家可以不用看这篇文章。但是,如果为了真正在未来可以胜任Java后台开发岗位,同时也不要被C/C++程序员鄙视,我建议大家可以认真学习这篇文章。因为,我们在这篇文章不只是讲理论,还会给出相应的Java代码可以让大家复制后实操作,从而来帮助理解这些专业的理论知识。

我们老九学堂直接拿《OPERATING SYSTEM CONCEPTS with JAVA Sixth Edition》专业原文书籍进行翻译解读,希望能够帮助非计算机专业的同学快速掌握操作系统理论。

因为我是计科系出身的程序员,所以下面所有的翻译内容只是给大家作为一个理解参考,请大家不要当成标准。如果有不足之处,请大家多包涵、指正和补充。

操作系统简介

  • 操作系统是一种程序*(An operating system is a* programm),该程序扮演了计算用户和计算机硬件之间的中介(中间人)角色
  • 操作系统的目标是:提供环境给用户,这个环境可以方便的、直接运行程序(in a convenient and efficient manner)
  • 操作系统必须确保计算机系统的正确操作,硬件必须提供相应的机制来阻止用户程序干扰系统的正常操作
  • 操作系统提供确定的服务程序给用户程序使用,以便容易的完成相应的任务

因为这种吹牛批的文章太多,所以我在这里就不累述了。请大家自行百度来理解。

进程概念

  • 一个进程可以被认为是一个执行中的程序(A process can be thought of as a program in execution)
  • 一个进程它需要确定的资源,比如CPU时间,内存文件和I/O设备,以便完成它的任务
  • 这些资源在进程被创建,并且运行时分配给进程使用
  • 进程是大多数操作系统的工作单元。我们可以把操作系统看成进程的集合:操作系统进程处理系统代码,用户进程处理用户代码。所有这些进程可以并发执行
  • 传统意义上讲,一个进程只包含一个线程(Thread)以控制它的运行,但是大多数现代操作系统都支持多线程处理:
    1. 创建和删除用户与系统的进程
    2. 进程调度(the scheduling of progresses)
    3. 规定同步机制、通讯机制,以及处理进程的死锁

因为这种吹牛批的文章太多,所以我在这里就不累述了。请大家自行百度来理解。

存贮管理

  • 计算机系统最主要的目的是执行程序。这些程序与它们访问的数据在程序执行时,必须放在主存中(main memory)
  • 为方便CPU运行,以及加速用户响应速度,计算机必须在内存中保持多个进程。所以,会存在大量的内存管理调度机制。内存调度机制依赖于硬件的支持
  • 因为大多数的主存都非常小,所以计算机系统必须提供辅存(secondary storage)来备份主存
  • 现代操作系统使用磁盘作为主要的在线(on-line)存贮介质,用来保存程序和数据

下面我们使用一张图来描述计算机中常见的存贮设备

image-20210319144119273.png

因为这种吹牛批的文章太多,所以我在这里就不累述了。请大家自行百度来理解。

存贮管理和I/O系统

  • 一个文件是相关信息的集合,这个集合是由文件创建者所定义的。文件的影射由操作系统来完成,它把内存的信息影射到物理设备中去
  • 文件一般在磁盘中被组织到目录中,以方便文件的操作和使用
  • 操作系统的I/O子系统提供简单的接口给用户进程使用,复杂的并发处理由操作系统完成

同样使用一张图来帮助大家理解

2.png

因为这种吹牛批的文章太多,所以我在这里就不累述了。请大家自行百度来理解。

分布式系统

  • 分布式系统是不同内存和时钟的进程集合。每个进程有自己的本地内存,它们之间的通讯通过局域网或者广域网实现
  • 在分布式系统中的处理器的型号和或能是不同的,比如有的是较小的实时设备,有的是PC机,有的是工作站,而有的是大型机,或者巨型机等组成
  • 分布式系统的好处是:用户访问资源由系统维护,所以计算速度和数据稳定性大大提高

我们也使用一张图帮助大家理解上现的话

1.jpg

因为这种吹牛批的文章太多,所以我在这里就不累述了。请大家自行百度来理解。

操作系统抽象

image-20210319144848584.png

我们从上面到的顺序参考翻译一下,如果有不足之处,请大家指正和补充:

  • user--最终用户即电脑使用者
  • compiler--编程器
  • assembler--链接器
  • text editor--文本编程器
  • database system--数据库
  • system and application programs--操作系统和应用程序
  • operating system--操作系统
  • computer hardware--计算硬件

在这上图的抽象中,我们归结成三个层次的抽象:

  • 硬件—中央处理器(CPU)、内存和I/O设备,它们给系统提供基本的计算资源
  • 应用程序—比如word字处理程序、工作表、编辑器和web浏览器等
  • 操作系统—控制相应的硬件,以及各种应用程序,以方便用户使用

也就是说,我们可以把操作系统可以简单地认为它是由硬件、应用程序和操作系统组成的,而我们使用Java开发的应用程序,它也是属于类似于word一样的应用程序。我们Java应用程序能够运行必须要依赖硬件、操作系统这两部支撑才能完成程序员想要的运行结果。虽然,我们知道初次学习Java时,一般都不需要知道硬件和操作系统的是什么,只要记住如下操作:

  • 下载JDK
  • 安装JDK
  • 配置Path
  • 弄个记事本应用

然后我们就可以使用Java开发编写程序了,紧接着我们马上就会听到一个专业术语:“面向对象编程”。

这个术语会一直伴随大家的Java开发过程,直到我们放弃!

Client-Server系统

由于PC机越来越便宜,并且性能越来越强大,原来大型机的终端机变成了了PC

image-20210319150226890.png

我来考翻译一下,如果有不足之处,请大家指正和补充:

  • Client--客户端放计算机,包括操作系统
  • network--网络系统
  • server-服务端计算机,包括操作系统

这种架构的系统一般来设计为计算服务器系统(compute-server system),它的客户端发送计算请求到服务器,服务器计算完成之后,响应结果给客户端。

第二种使用就是文件服务器系统(file-server system),它提供一种文件系统接口,客户端可以创建、更新和读取,以及删除这些文件。比如,Web服务器,它发送文件给客户端,然后客户端通过Web浏览器操作这些文件。

网络是计算机应用的根本,如果没有网络,那么我们不可能有今天非常发达的Web应用、大数据应用、分配式应用等等。很多人在学习Java编程时,都是使用一台笔记本电脑,然后配置服务器时都是localhost,根本不会去主动使用两台或者两台以上的电脑来组网编程!结果最终把自己学傻了。然后一旦真的就这样走上了工作岗位,那么就会出现非常尴尬致命错误,经常会闹出不可思议的笑话。相信出现这种情况肯定不是少数。

所以,我们建议大家在学习网络编程时,请务必把数据库器与自己客户端程序分开调试一下。我们老九学堂线下训练营教学时,所有服务器都不允许学生安装,学生只需要安装IDE就行了,然后通过局域网连接到我们的刀片服务器上:

  • MySQL
  • Redis
  • MongoDB
  • Kafka
  • Elastic Search
  • HBase
  • Nacos
  • FastDFS

这样可以让学生在学习的过程体会什么是网络编程的概念。

操作系统发展史

image-20210319151459383.png

我来考翻译一下,如果有不足之处,请大家指正和补充:

  • 1950年代~1960年代
    • mainframe--大型主机
    • no software--没有软件
    • compilers--出现编译器
    • resident monitors--监视器
    • batch--指处理
  • 1960年代~1970年代
    • minicomputers--小型计算机
    • time shared--分时系统
    • multiuser--多用户系统
    • networked--网络系统
  • 1970年代~1980年代
    • desktop computer--桌面计算机
    • multiuser--多用户系统
  • 1980年代~1990年代
    • distributed systems--分布式系统
    • multiprocessor--多处理器
    • interactive multiuser--多用户交互式系统
  • 1990年代~2000年代
    • fault tolerant--容错系统
    • multiprocessor fault tolerant--多处理器容错系统
    • multiprocessor networked--多处理器的网络系统
    • compilers interactive--交互式编译器

本人觉得这个图总结非常好,把一个非常漫长的操作系统发展演变史,用一终图就搞定了。

因为这种吹牛批的文章太多,所以我在这里就不累述了。请大家自行百度来理解。

小结

  • 操作系统是控制硬件的程序
  • 操作系统提供基本的系统级应用程序
  • 操作系统是用户与硬件之间的中介
  • 操作系统是运行系统进程和用户进程的平台

计算机系统组成

  • 现代计算机一般由一颗CPU和一些设备控制器和适配器组成
  • 这些设备通过总线(common bus)连接到共享内存(shared memory)
  • 每个设备控制器处理特定的设备,比如磁盘、输入设备、I/O总线以及视频、音频等
  • CPU和设备控制器是并发执行的,并且竞争共享内存资源。为处理这种竞争机制,内存控制器提供同步访问共享内存的功能

我们使用一张图来描述

image-20210319153812497.png

我来考翻译一下,如果有不足之处,请大家指正和补充:

  • Disks--磁盘
  • Mouse--鼠标
  • Keyboard--键盘
  • Printer--打印机
  • Monitor--显示器
  • CPU--中央处理单元
  • Disk Controller--磁盘控制器
  • USB Controller--USB控制器
  • Graphics Adapter--图形适配器
  • Memory--内存

因为这种吹牛批的文章太多,所以我在这里就不累述了。请大家自行百度来理解。

计算机运行原理

  • 计算机启动—开机或者重起计算机时,计算机必须一个初始化引导程序 (bootstrap program)运行。
  • 引导程序很简单,一般它被放在ROM(只读内存)硬件中。它初始化系统所有的方面,从CPU寄存器到设备控制器、内存等。
  • 引导程序必须知道的怎样装载操作,怎样启动执行系统程序。所以,引导程序把操作系统核心程序装载常驻内存中。
  • 之后,操作系统执行第一个进程,比如“初始化”,然后进入等待状态—等待事情出现。
  • 事件(event)的出现实际上是一个中断(interrupt)信号,这个信号来自硬件,或者软件。
  • 如果是硬件,那么可能产生一个系统呼叫(system call)又叫监视呼叫(monitor call)。
  • 现代操作系统是中断驱动(interrupt driven)的。如果没有进程处理,没有I/O服务器,没有用户操作响应,那么操作系统会非常安静。它会等待事情发生。
  • 事件就是中断或者是异常。异常(trap)是软件产生的,比如除零错误,非常内存访问等。
  • 单颗CPU的运行是中断驱动,如下图

image-20210319154643325.png

  • user process executing--用户进程执行
  • I/O interrupt processing--I/O中断处理
  • idle transferring--闲置转换
  • I/O request--I/O请求
  • transfer done--转换结束

因为这种吹牛批的文章太多,所以我在这里就不累述了。请大家自行百度来理解。

I/O结构

  • 对于I/O的异步操作时,操作系统会使用一个设备状态表(device-status table)来跟踪设备的使用状态。
  • 每个表中的项表示设备类型、地址和状态(闲置或繁忙)
  • 如果设备繁忙,那么请求类型与其它参数会保存在这个设备状态表中。因为可能是其它进程请求该设备,所以操作系统会给每个I/O设备维护一个等待队列(wait queue)—一个等待请求的列表。

参见下图所示

image-20210319160540449.png

我们使用下面的表格来描述上图中的设备状态表格

设备状态
keyboard(键盘)idle(闲置)
laser printer(激光打印机)busy(忙碌)
mouse(鼠标)idle(闲置)
disk unit 1(磁盘单元1)idle(闲置)
disk unit 2(磁盘单元2)busy(忙碌)
......

其中,address就是C/C++编程语言中使用指针变量保存的东西。

DMA传输

  • I/O操作比较慢,但是磁盘和网络通讯的速度是非常快的,它们的速度与内存操作的速度接近。
  • 如果CPU使用2毫秒来响应中断和中断到达,那么给进程处理业务逻辑时间不多。
  • 为解决这个问题,使用DMA (direct memory acces)技术来解决I/O高速操作的题。
  • 也就是I/O设备控制器把整个数据块,从自己的缓冲存贮区直接传送到内存,而不需要经过CPU中转一次。
  • 所有CPU的基本操作都是相同的。一个用户程序,或者操作系统本身都可能请求数据传输。
  • 操作系统查找一个缓冲(buffer)—如果空的,那么用来输入,如果是满的,那么用来输出—这个缓冲在缓冲池中。
  • DMA控制器启动I/O操作,在DMA执行数据传输期间,CPU空闲出来完成其它的任务。
  • 因为总体上一次可以作传送一个单词,所以DMA控制器可以从CPU的内存周期中“偷取”时间。

因为这种吹牛批的文章太多,所以我在这里就不累述了。请大家自行百度来理解。

网络结构

image-20210319161450728.png

  • Application Server--应用服务器
  • Workstation--工作站
  • Gateway--网关
  • Printer--打印机
  • Laptop--便携式电脑
  • File Server--文件服务器

这图是一个最典型的应用网络结构,其中工作站这个东西可能大家都没有见过。但是,本大黍上大学那会儿就是用的Unix小型机工作站学习编程的,它的工作原理可以类比现在最流行的云计算的概念。

因为这种吹牛批的文章太多,所以我在这里就不累述了。请大家自行百度来理解。

分布式系统中的进程通讯

image-20210319161915932.png

我来考翻译一下,如果有不足之处,请大家指正和补充:

  • communication subsystem--通讯子系统
  • network host--网络主机
  • user processes--用户进程
  • host operating system--主机操作系统

其中,LAN网络一般传输速度是大于100M/秒,WAN网络一般传输速度是56K/秒到大于1M/秒之间。

因为这种吹牛批的文章太多,所以我在这里就不累述了。请大家自行百度来理解。

小结

  • 计算机主要工作是执行程序
  • 程序必须在主存中执行
  • 主存是进程可以直接访问的最大区域
  • 访问单位从字节数组到百万和亿万个字节
  • 主存需要辅存持久保存大量的数据
  • 最常用的辅存是磁盘设备

操作系统组成结构

系统组件

从操作系统的角度讲,它需要考虑几个方面:

  1. 操作系统操作的服务
  2. 最终用户和程序可以使用的接口
  3. 操作系统组件以及这些组件之间的交互

创建一个操作系统是非常复杂的,所以只能把这个系统拆分成小块来处理。

系统的每个块都精心设计好,表示非常小心的设计了输入、输出和功能。

当然,不是所有的操作系统都有相同的结构。但是,大多数操作都有如下功能。

进程管理

如果程序的指令不在CPU中执行,那么程序本身没有什么作用。

一个程序(program)当处于运行状态时,此时就叫做进程(process)。

比如,word是最终用户使用的字处理程序,它是运行时就是一个进程;系统任务,比如打印机输出也是一个进程,因此,现在我们可以这定义进程,它是一个工作(任务”job”),或者是一个分时(time-shared)程序 。

一个进程需要确定的资源—CPU时间片、内存、文件和I/O设备—以便完成它的任务,这些资源在进程被创建时分配,直到进程结束时回收。

另外,进程被创建时还会有各种物理上和逻辑上的资源分配给进程,比如需要传送初始化数据,比如,进程需要在屏幕终端上显示文件状态,那么,需要在进程创建时把文件的名称,以相应的属性传送给进程。

注意:程序本身不是进程;一个程序是被动实体(passive entity),比如存贮到磁盘中的文件内容,而一个进程是主动实体(active entity)。

一个单线程的进程有一个程序计数器(program counter)用来指定下一个执行的指令,这种指令执行是必须是按顺序的,CPU执行一个一个的执行进程的指令,直到进程结束(指令结束)为止。

一般情况下,一个指令代表一个执行的进程,但是也可能两个进程是相同的程序,它们在执行时会使用相同的顺序执行指令。

通常情况下,一个程序在它运行时会包含很多进程,对于多进程就有多个程序计数器,每个计数器指向给定线程的下一个指令,进程是操作系统工作的单元,所以操作系统就是一个进程的集合。这些集合中分为操作系统进程和用户进程,所有进程都有并发执行—不管是多CPU还是单CPU

操作系统进程管理的职责如下:

  1. 创建和删除用户和系统进程
  2. 挂起和恢复进程
  3. 提供进程同步机制
  4. 提供进程通讯机制
  5. 提供进程死锁处理机制

因为这种吹牛批的文章太多,所以我在这里就不累述了。请大家自行百度来理解。

主存管理

主存是现代操作系统操作运行的核心,主存是一个范围从几千到上亿字节或者单词的数组。

每个单词或者字节都有自己的地址,主存是CPUI/O设备可以快速访问共享数据的仓储。

Von Neumann架构体系中,中央处理器在指令获取周期(instruction-fetch cycle)中,从主存读取指令,然后读数据;写操作时,中央处理器在数据获取周期(data-fetch cycle)中,向主存写入数据。使用DMAI/O操作方式时,设备控制器也是直接从主存读/写数据的。

主存是CPU可以直接访问的巨大存贮设备,为提高CPU和使用效率,以及计算机响应用户的速度,我们必须在内存中保持几个程序,用来完成内存管理。

操作系统负责与内存管理连接的职责:

  1. 当前内存的哪些部分被谁使用了
  2. 当内存空间可用时,决定哪些进程可以被装载到内存
  3. 分配和回收内存内容

文件管理

计算机可以保存各种不同类型物理媒体的信息。一般使用磁盘来实现这种信息的保存功能,每种媒体有自己特性和物理组织结构,每个媒体有自己设备控制器。

为方便操作系统使用,操作系统提供了统一的信息存贮的逻辑抽象—文件(file),操作系统会完成文件到物理媒体的影射,以及通过文件来访问者这些存贮媒体内容。

文件是一个由文件创建者定义的相关信息的集合。通常文件表示程序(包括源程序和目标程序),以及数据,数据文件可能是数值、字母或者二进制。文件可以是自由格式的(比如,文本格式),或者指定格式的。操作系统通过管理大块的存贮媒体来实现了抽象的文件概念。另外,文件是以目录的形式来组织,以方便文件的操作与使用。

操作系统与文件管理器的连接职责如下:

  1. 创建和删除文件
  2. 创建和删除目录
  3. 支持文件和目录的权限操作
  4. 备份文件到持久介质

I/O系统管理

操作系统有一个目的含义是隐藏硬件设备的特性,比如UNIX操作系统中把I/O设备通过I/O子系统来隐藏。

I/O子系统由以下部分组成:

  1. 内存管理组件,包括buffering(缓冲器), caching(缓存)和spooling(池)
  2. 通用的设备驱动接口
  3. 特定的硬件驱动程序

只有设备驱动程序知道特定的硬件设备

辅存管理

主存是所有程序运行的地方,但是它相对所有的数据和程序时非常小,并且掉电时数据会丢失,所以计算机系统必须提供辅助存功能,来备份主存,大多数现代计算机使用磁盘来作为主要的在线存贮媒体,用来保存程序和数据!

大多数程序,包括编程器、汇编器和字处理程序等都保存到磁盘中,直到它们被装载到主存之后才能运行,正确的辅存管理是计算机系统最重要的部分。

操作系统与磁盘管理连接的职责是:

  1. 释放空间管理
  2. 存贮分配管理
  3. 磁盘调度

网络管理

分布式系统(distributed system)是一种进程的集合,这些进程分别在不同的共享内存,使用不同的资源设备。

进程通讯是通过各种数据线,比如高速总线、有线网络、无线网络等。

处理器包括微处理器、工作站处理器、PC处理器、手持设备处理器、小型机处理器,以及大型机处理器。

随着http协议出现,浏览器向web服务器请求资源时不需要输入用户名和密码,于是分布式系统得到了广泛应用。

保护系统

如果计算机系统有多个用户,那么会允许并发执行多个进程,于是要求不同进程必须与其它进程隔离,为此,机器系统必须确保文件、内存片断、CPU和其它被操作资源只能通过操作系统授权才可以使用。比如,内存地址硬件确保一个进程只能在自己的地址空间中执行,计数器确保如果CPU没有彻底放弃控制时,所有进程不能获取控制权。

命令解释系统

设备控制寄存器不会被用户直接访问,所以各种外部设备是受到保护的,保护机制意味提供了授权和未授权的使用方式。

在操作系统有一个最重要的系统程序就是命令解释程序(command interpreter),它是用户和操作系统之间的接口。

一些操作系统把命令解释器作为核心的一部分,而MS-DOSUNIX则把命令解释器作为特定的程序,该程序在用户登录时初始化。大多数命令是通过控制语句来实现的。用户登录到操作系统之后,如果一个程序读入这些命令,那么命令解释器会解析这些命令语句,然后自动执行系统命令,这种读取控制命令的程序叫做控制卡解析器(control-card interpreter),或者壳(shell)程序。

它们功能很简单,获取下一个命令语句,然后执行它。不同于shell程序的应用是鼠标和菜单的应用系统,这就是我们熟知的MacintoshMicrosoft Windows的窗体操作系统。

鼠标移动图片、图标上,屏幕表示程序、文件和系统功能,根据鼠标指针的位置,当点击鼠标按钮时会呼叫一个程序,表示选择一个文件或者目录—也就是文件夹(folder),或者点击下拉菜单中的命令。当然更复杂、更强大的是使用shell语句,但是学习使用时比较困难。

操作系统服务

命令语句自身处理进程创建和管理、I/O操作、辅存管理、主存管理、文件系统访问、保护功能和网络功能。

一个操作系统提供了一种程序执行环境。也就是它提供了确定的服务程序给用户和用户程序使用,这些服务程序是为了程序员方便完成他们的任务。

操作系统提供的服务功能如下:

  • 程序执行:系统必须能够装载一个程序到主存,然后运行它。
  • I/O操作:一个运行的程序可以请求I/O设备。用户不能直接操作I/O设备,所以,操作系统必须提供I/O操作功能。
  • 文件系统操作:程序需要读/写文件。
  • 通讯:一个进程需要与其它的进程通讯。通讯功能通过共享内存(shared memory)和消息传送(message passing)来完成。消息传送是指操作系统之间的信息包传送机制。
  • 错误侦测:操作需要不断侦测可能的错误。错误会出现在CPU和内存硬件(比如掉电)、I/O设备(比如网络掉线,打印机缺纸),以及用户程序(比如,算法错误,访问非法内存区域,以及占用太多CPU时间)。
  • 资源分配:当有同一时间出现多用户、用任务运行时,资源必须分配到所有用户。比如CPU时间片、主存空间、文件存贮等。
  • 审计(Accounting):追踪用户使用了哪些资源,以及什么类型的资源。这种服务器是为了计算用户什么时候需要付费,或者统计用户的行为。
  • 保护和安全:在多用户计算机系统中有自己的信息。安全系统是非常的重要的,这需要授权机制,以保护用户的资讯安全。

系统呼叫

系统呼叫(System calls)提供了进程和操作系统之间的接口。这些呼叫一般被汇编语言指令所使用。

很多操作系统允许高级语言直接进行系统呼叫,一般这种形式是宏定义函数或者过程的方式实现。比如C/C++语言就是用来替换汇编语言的。这些语言可以直接进行系统呼叫。在UNIX操作系统中允许C/C++程序进行系统呼叫,在Windows操作系统Win32 API进行系统呼叫。

系统呼叫大约可以分为五大类:

  • 进程控制(process control)
  • 文件操作(file manipulation)
  • 设备操作(device manipulation)
  • 信息维护(information maintenance)
  • 通讯(communications)

图示如下:

3.png

系统程序

从另外一个角度讲,现代操作系统是一个系统程序的集合,系统操作给程序员提供了方便的开发和执行环境。它们分为下面几大类:

  • 文件管理:程序创建、删除、拷贝、改名、打印输出文件和目录
  • 状态信息:请求系统日期、时间、可用内存空间、当前用户数等状态信息
  • 文件修改:使用文本编程器创建和修改保存在磁盘中的文件内容
  • 编程语言支持:通用编程语言的编辑器、汇编器和解释器,比如C/C++Java, VBPERL语言
  • 程序装载和执行:一旦程序被汇编或者被编辑之后,必须被装载到内存去执行。系统提供装载器、连接器、调试器等
  • 通讯:创建进程、用户和计算机系统之间的连接。允许用户发送消息给屏幕、浏览器,发送Mail,文件传输和远程日志等

此外,我们最终用可以使用系统程序用来解决通用的问题和操作。比如使用Web浏览器、字处理器和文本编辑器、数据库系统、文本编辑器和游戏等解决一般性问题。这就是我们熟知的系统功能(system utilities)和应用程序(application programs)。

操作系统结构

image-20210319170208979.png

我来考翻译一下,如果有不足之处,请大家指正和补充:

  • application program--应用程序
  • resident system program--驻留系统应用程序
  • MS-DOS device drivers--MS-DOS设备驱动器
  • ROM BIOS device drivers--ROM BIOS设备驱动器

操作系统分层结构

无标题.png

我来考翻译一下,如果有不足之处,请大家指正和补充:

  • new operations--新操作
  • layer M--M层级
  • hidden operations--隐藏操作
  • existing operations--现存的操作

操作系统模型

无标题1.png

我来考翻译一下,如果有不足之处,请大家指正和补充:

  • processes--进程
  • kernel--内核进程
  • hardware--硬件设备
  • VM--Virtual-machine(虚拟机)
  • virtual-machine implementation--虚拟机实现

小结

  • 操作系统一般有10系统组件
  • 进程管理是管理系统进程和用户进程的组件
  • I/O管理是主存和辅存交互的核心
  • 辅存管理是文件管理的前提条件
  • 网络管理与I/O操作关联非常紧密
  • 命令解释管理是用户直接操作系统的接口
  • 系统呼叫是用户程序直接操作系统的接口

实践代码

模拟进程

看了这么多抽象的理念,我们在书写Java代码来模拟多进程的概念:

import java.util.*;
import java.io.*;

/**
	功能:书写几个类用来模拟MQ系统使用(使用多线程来模拟多进程)
	作者:技术大黍
	说明:生产者-消费者模型用来解决多线程数据同步问题,以及可以用来解决Socket网络中
		  消息的同步机制。
	*/
public class DemoMQ{
	
	public DemoMQ(){
		try{
			MessageQueue mq = new MessageQueue();
			ConsumerMQ consumer = new ConsumerMQ(mq);
			ProducerMQ produre = new ProducerMQ(mq);
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args){
		new DemoMQ();
	}
}
/**
	定义一通道用来说明MQ的操作行为
	*/
interface Channel{
	public void send(Object item); //发送消息到通道
	public Object receive(); //从通道获取消息
}

/**
	功能:通道实现类
	*/
class MessageQueue implements Channel{
	private Vector queue;
	
	public MessageQueue(){
		queue = new Vector();
	}
	
	public void send(Object item){
		queue.addElement(item); //给通道添加消息项
	}
	public Object receive(){
		if(queue.size() == 0){
			return null;
		}else{
			return queue.remove(0);
		}
	}
	
	public Vector getQueue(){
		return queue;
	}
}

/**
	功能:模拟生产者进程
	*/
class ProducerMQ extends Thread{
	private MessageQueue queue;
	int count = 0;
	boolean isRun = true;
	
	public ProducerMQ(MessageQueue queue){
		this.queue = queue;
		start();
	}
	
	public void run(){
		try{
			while(isRun){
					count++;
					Date message = new Date();
					queue.send(message.getSeconds());
					System.out.println("生产消息:" + message);
					
					this.sleep(1000);
					if(count == 10){
						isRun = false;
					}
				}
				this.interrupt();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}

/**
	功能:模拟一个消费者进程
	*/
class ConsumerMQ extends Thread{
	private MessageQueue queue;
	int count = 0;
	boolean isRun = true;
	
	public ConsumerMQ(MessageQueue queue){
		this.queue = queue;
		start();
	}
	
	public void run(){
		try{
			while(isRun){
				count++;
				if( queue.getQueue().size() != 0){
					System.out.println("消费消息:" + queue.receive());
				}
				
				this.sleep(1000);
				if(count == 10){
					isRun = false;
				}
			}
			System.out.println("消费消息:" + queue.receive());
			this.interrupt();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}

Java进程的多线程

/**
	功能:书写几个类用来演示线程私有数据的使用方式
	作者:技术大黍
	*/
public class DemoThreadLocal{
	public DemoThreadLocal(){
		try{
			Worker testee = new Worker();
			testee.start();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args){
		new DemoThreadLocal();
	}
}

/**
	指定一个关联ThreadLocal的类
	*/
class Service{
	private static ThreadLocal errorCode = new ThreadLocal();
	
	public static void transaction(){
		try{
			int a = 1;
			int b = 0;
			int c = a / b;
		}catch(Exception e){
			errorCode.set(e);
		}
	}
	
	public static Object getErrorCode(){
		return errorCode.get();
	}
}

/**
	功能:使用一个线程来获取另外一个线程的信息
	*/
class Worker extends Thread{
	private static Service provider;
	
	public void run(){
		provider.transaction();
		javax.swing.JOptionPane.showMessageDialog(null,"来自主线程的错误:" + 
			provider.getErrorCode());
	}
}

CPU调度和死锁处理


/**
	功能:书写几个类用来演示CPU调试和死锁现象
	作者:技术大黍
	*/
public class DemoDeadLock{
	
	public DemoDeadLock(){
		try{
			Mutex mutexX = new Mutex();
			Mutex mutexY = new Mutex();
			A a = new A(mutexX,mutexY);
			B b = new B(mutexX,mutexY);
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args){
		new DemoDeadLock();
	}
	
}

/**
	功能:指定一个互斥对象
	*/
class Mutex{
	
}

/**
	功能:需要线程来模拟进程出现死锁
	*/
class A extends Thread{
	private Mutex first, second;
	private boolean isRun = true;
	private int count;
	
	public A(Mutex first, Mutex second){
		this.first = first;
		this.second = second;
		start();
	}
	
	public void run(){
		while(isRun){
			count++;
			if(count == 10){
				isRun = false;
			}
			System.out.println("B线程运行中。。。");
			synchronized(first){
				System.out.println("A类对象操作互斥对象first");
				
				synchronized(second){
					System.out.println("A类对象操作互斥对象second");
				}
			}
		}
	}
	
}

class B extends Thread{
	private Mutex first, second;
	private boolean isRun = true;
	private int count; 
	
	public B(Mutex first, Mutex second){
		this.first = first;
		this.second = second;
		start();
	}
	
	public void run(){
		while(isRun){
			count++;
			if(count == 10){
				isRun = false;
			}
			System.out.println("B线程运行中。。。");
			synchronized(first){
				System.out.println("B类对象操作互斥对象first");
				
				synchronized(second){
					System.out.println("B类对象操作互斥对象second");
				}
			}
		}
	}
	
}

内存影射文件

import java.io.*;
import java.nio.*;
import java.nio.channels.*;
/**
	功能:演示内存文件影射
	作者:技术大黍
	*/
public class FileMapDemo{
	private static final int PAGE_SIZE = 4096;
	
	public FileMapDemo(String[] args)throws Exception{
		if(args.length != 1){
			javax.swing.JOptionPane.showMessageDialog(null,"java FileMapDemo 文件名");
			return ;
		}else{
			RandomAccessFile inFile = new RandomAccessFile(args[0], "r");
			FileChannel in = inFile.getChannel();
			MappedByteBuffer mappedBuffer = in.map(
				FileChannel.MapMode.READ_ONLY, 0, in.size());
			long pageNum = in.size() / (long)PAGE_SIZE;
			if(in.size() % PAGE_SIZE >0){
				++pageNum;
			} 
			int position = 0;
			
			for(long i = 0; i < pageNum; i++){
				byte item = mappedBuffer.get(position);
				position += PAGE_SIZE;
			}
			int length = (int)inFile.length();
			byte[] chars = new byte[length];
			for(int i = 0; i < length; i++){
				chars[i] = mappedBuffer.get(i);
			}
			String showMessage = new String(chars);
			System.out.println(showMessage);
			
			in.close();
			inFile.close();
			
		}
	}
	
	
	public static void main(String[] args){
		try{
			new FileMapDemo(args);
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}

网络通讯RMI

RMI服务端

import java.rmi.*;
import java.rmi.server.*;
import java.util.*;
/**
	功能:书写几类用来演示RMI的进程呼叫
	作者:技术大黍
	使用:javac DemoRMI.java
		  rmic RemoteDateImpl
		  rmiregistry & (for unix)
		  start rmiregistry (for windows)
		  java DemoRMI
	*/
public class DemoRMI{
	public DemoRMI(){
		try{
			RemoteDate dateServer = new RemoteDateImpl();
			Naming.rebind("DateServer",dateServer);
			System.out.println("远程日期服务已经启动。。。");
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args){
		new DemoRMI();
	}
}


/**
	功能:定义的远程接口对象
	*/
interface RemoteDate extends  Remote{
	public abstract Date getDate()throws RemoteException;
}

/**
	功能:书写一个远程接口实现类
	*/
class RemoteDateImpl extends UnicastRemoteObject implements RemoteDate{
	
	public RemoteDateImpl()throws RemoteException{
		
	}
	
	public Date getDate()throws RemoteException{
		return new Date();
	}
	
	
}

RMI呼叫客户端

 import java.rmi.*;

/**
	功能:书写一个实现RMI通讯的客户端应用
	作者:技术大黍
	*/
public class ClientRMI{
	
	public ClientRMI(){
		try{
			String host = "rmi://127.0.0.1/DateServer";
			RemoteDate dateServer = (RemoteDate)Naming.lookup(host);
			javax.swing.JOptionPane.showMessageDialog(null,dateServer.getDate());
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args){
		new ClientRMI();
	}
}

总结

我们Java应用开发程序员虽然不需要班科出身就可以胜任,但是如果我们想成为厉害的后端程序员,那么了解和学习计算机硬件和操作系统原理是必要的。我们希望通过这篇文章可以抛砖引玉,快速带领大家入门理解计算机组成的基础概念和操作系统基本原理,早日成为资深的专业人士!

最后

感觉有用的同学,请记得给大黍❤️关注+点赞+收藏+评论+转发❤️

作者:老九学堂—技术大黍

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值