操作系统简介

操作系统主要作用

  1. 给用户层提供一个统一的接口
  2. 管理硬件资源

操作系统硬件资源

主要有:处理器,内存,硬盘,I/O设备,总线

其中处理器有一些概念(其实就是处理器的特殊寄存器)需要了解一下:程序计数器(program counter),堆栈指针(stack pointer)以及程序状态字(PSW)

  • 程序计数器就是对程序员可见的一组寄存器,其包含下一条指令要拉取的内存地址
  • 堆栈指针是指向当前内存栈顶的指针
  • 程序状态字包含一些条件代码位,可以被不同的指令设置。主要是CPU优先级,用户还是内核模式和其他的控制位

而且处理器有多核和单核处理器,所以引申出来就有多线程,多进程,超线程等等的概念,有了多线程后,就有了资源竞争,而后有了锁,调度,上下文切换等一系列的问题出现

内存主要有RAM(random access memory), ROM(read-only memory), EEPROM(electrially erasable PROM)和闪存(flash memory)。由于内存的大小有限制,所以有了虚拟内存,虚拟化,地址空间等概念,而且内存的内容是断电即失的,所以需要保存到硬盘上,也就有了文件系统。硬盘和内存之间的内容交换又有相应的页面置换算法的研究,其中有一个重要的概念MMU(memory management unit)

I/O设备主要是用来输入输出,因为需要及时反馈,所以又有了中断的方案来解决优先处理

总线是为了处理额外的扩展,常见的是PCIe总线接口,可以扩展网卡和硬盘等,usb也是总线的一种

还有一个重要的东西叫BIOS(basic input output system),这个是用来在计算机启动阶段进行自检的程序,主要是检查上述的硬件资源,从而进行统一管理

操作系统概念

其实有些概念上面已经提到了,这里只是更加细致介绍一些概念

进程

一个进程通常是一个正在运行的程序。

进程主要包含以下内容:

  • 地址空间(address space),地址空间通常是一些列可读可写的内存地址,它包含了可执行程序,程序数据和堆栈信息
  • 寄存器。程序计数器和堆栈指针
  • 一堆文件描述符
  • 告警信息
  • 相关进程列表
  • 其他需要的信息

进程切换的时候,需要保存进程运行的状态信息,大部分操作系统都是使用一个进程表(process table)来维护,挂起的进程通常由地址空间和进程表入口组成

进程可以创建子进程,如果两个进程之间需要同步信息,这称为进程间同步(interprocess communication)

进程在内存中分为代码段(text segement), 数据段(data segement)和堆栈段(stack segement)

后面会继续写进程和进程间通信相关知识

地址空间

地址空间的主要目的是保护使用更大的内存空间

每个进程拥有自己的地址空间,地址空间有实际物理内存大小,在进程切换的时候,进程独占内存地址,从而让进程看起来能够使用更大的地址空间

文件

文件是将处理器和内存中容易丢失的内容,保存在硬盘中,所以文件可以理解成硬盘内容的抽象。系统调用需要提供创建文件,删除文件,读取文件和写入文件的操作

大部分系统都提供一个目录(directory),把多个文件集中在一起。主要模型如下

文件也有操作权限,所以也相对来说提供了保护

文件中的概念比较多,这里介绍基本的一些概念

  • 文件描述符(file descriptor)。文件打开操作时,会返回一个文件描述符,后续操作可以通过这个文件描述符操作
  • 挂载文件系统。外部存储,如U盘,需要被操作系统读写的时候,需要先挂载到文件系统后,才能进行操作
  • 特殊文件(special file)。特殊文件主要是将I/O设备抽象成文件,然后进行读写。可以分为块特殊文件(处理磁盘)和字符特殊文件(处理打印机等)
  • 管道(pipe)。管道其实是进程和文件两个相关的一个概念,管道是一种伪文件,可用于连接两个进程

保护

操作系统保护是一个很大的议题,有很多内容可以深挖。我们用户层面可以看到文件保护,在网络中,就有更多的保护议题,具体后面看情况介绍

Shell

shell是大部分程序员都要接触到的东西,能够输入各种程序指令,从而完成想要的工作。这部分可以参考MIT 6.NULL。还是要建议看下shell的操作

系统调用

系统调用(system call)是用户态的进程调用内核态的函数的方式。比如读取的系统调用过程

介绍一些系统调用的用法

进程相关

  • pid = fork()。创建一个子进程,并返回pid
  • pid = waitpid(pid, &statloc, options)。等待子进程挂起
  • s = execve(name, argv, environp)。替换进程的地址空间
  • exit(status)。中断进程执行并返回状态

文件操作

  • fd = open(file, how, ...)。打开文件,并标记读写权限
  • s = close(fd)。关闭文件
  • n = read(fd, buffer, nbytes)。读取数据到缓冲区
  • n = write(fd, buffer, nbytes)。写缓冲区到文件
  • positon = lseek(fd, offset, whence)。移动光标
  • s = stat(name, &buf)。获取文件状态信息

文件目录管理

  • s = mkdir(name, mode)。创建一个目录
  • s = rmdir(name)。 删除一个空目录
  • s = link(name1, name2)。创建一个新入口name2指向name1
  • s = unlink(name)。删除一个目录入口
  • s = mount(special, name, flag)。挂在一个文件系统
  • s = umount(special)。卸载一个文件系统

其他

  • s = chdir(dirname)。 切换工作目录
  • s = chmod(name, mode)。修改文件保护位
  • s = kill(pid, signal)。 发送一个信号给进程
  • seconds = time(&seconds)。从Jan. 1, 1970开始获取过去的时间
posted @   xnzone  阅读(262)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示