2017-10-10 18:46:14 duliangjiao 阅读数 769

这一章主要对Unix系统的整个结构、进程间的关系以及内核进行了简要的描述。
系统结构
图1给出了Unix系统的体系结构。该图的中心部分是硬件,它向操作系统提供基本的服务。操作系统部分直接和硬件进行交互,并向程序提供公共服务,使它们同硬件特性隔离开来。这样一来的话,如果程序对硬件没有做什么假定的话,那么它就具有很高的可移植性。外层的程序,例如shell及编辑程序等等,是通过引用一组明确定义的系统调用而与内核交互的。

这里写图片描述
图1
系统高层特征
文件系统的特点
1. 层次结构,如图2。文件系统被组织成树状结构,树有个称为根(root)的节点(记作“/”)。其中每个非叶子节点都是文件的一个目录,而叶节点的问题既可以是目录也可以是正规文件还可以是特殊文件。
这里写图片描述
图2
2. 对文件数据的一致处理。在UNIX系统中,程序是不需要了解文件的内部存储格式,而是把数据统一看成无格式的字节流。所以程序可以按照自己的意愿来解释字节流。
3. 文件数据的保护。在Unix系统中,对一个文件的存取许可权是由与该文件相联系的访问控制权所控制的,存取许可权能够分别对文件所有者,同组用户以及其他人这三类用户独立地建立存取许可权,以控制读、写及执行的许可权。

处理环境
一个程序是可执行文件,而一个进程是一个执行中的程序的实例。在UNIX系统上可以同时执行多个进程。特别的是,一个程序是可以有着多个相对应的进程。进程可以通过各种系统调用来创建新进程、终止其他进程以及进行进程间的通信等等。

操作系统的服务

  1. 进程管理
  2. 存储管理
  3. 文件管理

内核
在UNIX系统上用户进程的执行分为两个级别:用户与内核。当发生系统调用时,进程的执行态从用户态变成内核态。用户态和内核态的区别主要在于:在用户态下的进程能存取它们自己的指令和数据,但是不能存取内核指令和数据,然而内核态下的进程是可以存取内核和用户地址的。但是内核并不是与用户进程平行运行的孤立的进程集合,而是每个用户进程的一部分。相应地,每一个进程的虚拟地址空间划分为仅在内核态下可存取及在内核态、用户态下都可存取的两部分。

2019-08-29 14:00:48 qq_36321889 阅读数 43

这一小节忘记用markdown写了,有点乱,后面使用markdown排版,会好很多!
在这里插入图片描述
在这里插入图片描述
UNIX的系统结构:
在这里插入图片描述
UNIX V系统中,有64个系统调用,其中32个是常用的。

shell是什么程序?命令解释程序!!!

shell把命令行的第一个字解释称命令名,对所有命令,shell都创建子进程,子进程执行与该名字相联系的命令。把命令行中其余字视为该命令的参数。

shell允许三类命令:
1. 可执行文件
2. 包含一系列shell命令行的可执行文件,shell脚本?
3. 内部命令!内部命令是一种程序设计语言,包括用于循环的命令,用于条件的命令等,以及改变进程的当前目录的命令以及其他一些命令。

shell默认使用同步执行的方式,当然也可以异步执行,那么如何异步执行呢?比如who即是同步执行,通过敲入who &系统则在后台执行程序who:
在这里插入图片描述
构件原语:UNIX系统的宗旨是提供操作系统原语,使用户能书写小的、模块式的程序,并把它们作为构件去构筑更复杂的程序。

这里所谓的原语可以简单理解成接口吧
1. 比如重定向IO即使为shell用户可见的一个原语
2. 第二个构件原语为pipe,允许在读者进程与写者进程之间传递数据流的机制。这样就实现了进程间通信机制。

系统希望我们设计这样的程序:使用上述两个原语,目的是,其他程序也能借助我们设计的程序,就是说不用重复造轮子嘞。

也就是IO重定向和管道是至关重要的;比如:grep main a.c b.c c.c 搜索一个文件的集合,即在a.c b.c c.c三个文件中搜索包含main的行,将对应行打印到标准输出。同时wc能对标准输入文件中的行数进行计数,所以就组合成了:grep main a.c b.c c.c | wc -l,这就是上文描述的思想。

总结:IO重定向和管道算是操作系统提供给我们的原语,好处是,我们能通过管道将很多应用程序连接起来,最简单的例子就是grep main a.c b.c c.c | wc -l操作系统服务:由操作系统提供的服务有:就是几大模块呗:进程管理模块、文件系统模块、进程调度、内存管理、缓存管理
1. 通过允许进程创建、终止、挂起以及通信来控制进程的执行。
2. 对进程在CPU上的执行进行公平调度
3. 给进程分配内存
4. 文件系统的构建
5. 对各种设备进行有控制的存取

关于硬件的假设:UNIX中只有两个执行级别:用户态和核心态,虽然很多机器都支持比这里所说的两个级别多的级别,但是对于UNIX来说,用户态-3和核心态-0就足够了!

两个态的区别是:访问权限+特权指令的区别。

中断与例外:UNIX系统允许IO外围设备或系统时钟异步地中断CPU,当接收到中断的时候,核心保存它的当前上下文、判断中断原因、为中断服务。在核心为中断服务之后,核心恢复被中断的上下文,继续进行-这里涉及到上下文切换,在Linux内核中使用了一个数据结构;

例外即是内存越界、除数为0等。中断和例外的区别:
1. 中断发生在两条指令之间,而例外发生在一条指令执行的过程中。注意是指令,即执行了某条指令才引发中断,同理,即使触发时钟中断,CPU也应该执行完那条执行再去处理,指令执行一半的情况好像没有;而例外呢?好像没有那么讲究,什么时候出了错什么时候报错叭~~~
2. 中断处理完之后继续执行下一条指令,而例外执行完之后重新启动该指令。为什么要重启呢?因为之前的指令执行出错,没有执行完,所以重新执行一遍;

处理机执行级:即中断是分级别的,比如我们在操作链表的时候,不希望接收到磁盘中断,就屏蔽掉一些低级中断,emmmm,Linus 的代码中是直接将中断关掉了,操作完之后再将中断打开···后面就会讨论到,有很多因为sleep导致的竞争关系,比较复杂,而且这些竞争关系大多都是因为IO陷入sleep而导致的;

内核中的处理方法也比较暴力,直接关中断,这也会带来一些问题,比如中断延迟、响应时间边长等,正如Linus所说,希望cli, sti中间的代码执行得很快;

存储管理:大概描述了下虚拟地址和物理地址,说是通过硬件来映射的,原因呢?因为它太频繁了,设计成硬件的好处是:快,超级快的那种哦~

本章小结:系统设计鼓励程序员书写小程序,每个小程序都只做几个操作但做的很好,然后通过管道和IO将这些小程序组合起来去做更复杂的操作。这应该适用于shell编程那块叭!当然现在我们仍然可以这样写,而且这样写起来也很炫酷~!@#

核心除了提供系统调用外,还提供一些基础服务,比如内存分配,进程分配空间等,中断的处理等。UNIX的核心省略了很多没有必要的功能,只提供一些系统调用,系统调用提供了一些很必要的功能,即没有这些系统调用,这些功能是无法实现的。

2007-07-19 20:22:00 lanhuahua 阅读数 536
 
第一章登录和退出
用户在登录前,首先要向系统管理员申请一个用户注册名,不论用户从哪台计
算机登录到ITPNET 上都将访问相同的文件系统。
1.1 登录
当屏幕上出现Login 提示符时,用户可以输入自己的用户注册名,并按回车键。
若有口令,系统将提示用户输入密码,并按回车键,口令输入正确后,用户登录成
功。这时,屏幕上会显示出一些信息和命令提示符。如:
Login: guest [Enter]
passwd: ****** [Enter]
sun%
注: 用户名要用小写字母输入,UNIX 系统区分大小写字母。
1.2 退出
当用户准备退出自己的计算机帐号时,可在系统示符下输入logout 或exit 或按
[Ctrl-D]。当屏幕出现Login 时,用户可以安全地离开计算机了。如:
sun% logout [Enter]
Login:
1.3 修改口令
为了防止他人使用自己的帐号,在你首次登录后,请用passwd 命令修改只有本
人知道的保密口令,口令通常由此可6 到8 个字母数字组成。如:
sun% passwd [Enter]
Old Passwd: ******
New Passwd: ******
Retype New Passwd: ******
注:当你退出系统再次登录时,就要使用新的口令。
 
2019-11-28 15:25:29 sinat_17700695 阅读数 8

第一章 Unix基础知识

1.引言

操作系统为应用软件提供服务,包括调度进程,管理内存,文件系统,网络协议栈,设备驱动等等。

2.Unix体系结构

内核 -> 系统调用 -> shell & 公用函数库(e.g. glibc) -> 应用程序
内核 -> 系统调用 -> 应用程序
在这里插入图片描述
补充:执行应用程序时处于用户态,进行系统调用后进入内核态

3.登录

1.登录文件:/etc/passwd 文件
2.命令行解释器shell:Bourne shell,Korn shell和Bourne-again shell,dash(Debian Almquist shell)

4.文件和目录

1.文件系统:目录和文件的一种层次结构
2.文件名
3.路径名 :遍历路径下文件ls实现,dirent.h头文件、opendir函数、readdir函数
4.工作目录:进程具有自己的工作目录,可以用chdir函数更改进程的工作目录
5.起始目录:被加载为启动时的工作目录

5.输入和输出

1.文件描述符
2.标准输入、标准输出和标准错误 : 标准输入输出的文件描述符 STDIN_FILENO 和 STDOUT_FILENO
3.不带缓冲的IO: open、read、write、lseek和close,都使用文件描述符对文件操作
4.标准IO: 如gets,为不带缓冲的IO提供了一个缓冲(有块缓冲、行缓冲和无缓冲)
补充:标准IO属于公共函数库的范畴,而不带缓冲的IO属于系统调用的范畴

6.程序和进程

1.程序:未被加载的代码,被内核exec
2.进程和进程ID:程序的执行实例为进程,每个进程有自己的进程ID
3.进程控制:fork,exec和waitpid
4.线程和线程ID:线程是某一时刻执行的一组机器指令,通常一个进程只有一个控制线程,多控制线程可以利用多核能力
思考:进程用于调度不同程序?(内存),线程用于用于调度不同CPU核?(执行)

7.出错处理

1.errno值:当Unix的系统(内核与系统调用)函数出错时,通常该函数会返回一个负值,且(该进程或线程?)事先定义的一个整型变量errno将会被设置为一个具有特定信息的值。
如open函数出错时会返回-1,且此时errno会被赋值为15种不同errno值(如权限不够、文件不存在)之一。
可以使用strerror(int errnum)函数或者perror(const char *msg)函数将errno的值转换为其对应的字符串信息。

#include <stdio.h>
#include <stdlib.h>    //  exit函数头文件
#include <string.h>    //  strerror函数头文件
#include <errno.h>     //  errno变量

int main(int argc,char *argv[] )
{
	// EACCES 是一个errno的可能的取值之一,在errno.h中定义
	fprintf(stderr,"EACCES:%s\n",strerror(EACCES) );
	// errno变量,在每一个进程/线程中由内核为其创建,在errno.h中声明
	errno = ENOENT;   // ENOENT 是一个errno的可能的取值之一,在errno.h中定义
	// perrno函数会自动将进程中的errno变量读取并转换为字符串信息
	perror(argv[0] );
	exit(0);
}

输出如下:

EACCES:Permission denied
FIle: No such file or directory

2.出错恢复:致命性出错一般只能打印后退出;非致命性错误如资源短缺可以延迟后再重试,资源相关的非致命性错误包括EAGAIN、ENFILE、ENOBUFS、ENOLCK、ENOSPC、EWOULDBLOCK等

8.用户标识

1.用户ID:用于让系统标识不同的用户,root用户的用户ID为0( 或用户ID为0的用户为根用户或超级用户),用户ID是口令文件登录项的一个属性
2.组ID:也是口令文件登录项的一个属性,同组用户可以通过修改权限设置共享文件,用户ID和用户组ID是为了让磁盘上的文件不需要存储ASCII登录名及组名,而只需要4个字节存储ID就可以了,用户ID与用户登录名、组ID与组名的映射关系存在于口令文件和组文件中,组文件通常是/etc/group
3.附属组ID:一个用户可以存在于多个附属组中

9.信号

信号用于通知进程发生了某种情况,进程对于信号可以有三种处理方式:忽略信号、按系统默认方式处理或者提供一个函数以备信号发生时调用,即捕捉信号

10.时间值

1.Unix的时间包括日历时间和进程时间,日历时间即自UTC(70年1月1日00:00:00)以来的时间,用类型time_t保存;进程时间是度量进程使用的中央处理器资源的时间,也称CPU时间,用类型clock_t保存。进程时间用时钟滴答计算,每秒钟曾被分为50、60和100个滴答。
2.Unix系统为每一个进程维护3个进程时间值,包括:
(1)时钟时间:又称墙上时钟时间,是进程运行的时间总量,值与系统中同时运行的进程数有关;
(2)用户CPU时间:执行用户指令所用的时间;
(3)系统CPU时间:为该进程执行内核程序所执行的时间,如read、write耗时;

11.系统调用和库函数

1.系统调用:直接进入内核的入口点
2.库函数:有可能wrap了系统调用,有可能没有使用系统调用,如strcpy和atoi
malloc与sbrk关系及其模型
小结:第一章介绍Unix的一些基础知识以及Unix系统为维护一个进程、文件系统等所提供的一些内容。

2019-04-21 21:18:50 myz123321 阅读数 98

第一章 UNIX基础知识

一:主要内容
  第一章主要介绍了UNIX体系结构、登录、文件和目录、输入和输出、程序和进程、出错处理、用户标识、信号、时间值、系统调用和函数。

二:UNIX体系结构
  UNIX是一个操作系统,操作系统可以定义为一种软件,控制计算机硬件资源,提供程序运行环境。我们通常叫这种软件为内核。UNIX操作系统包括以下几个部分,由内到外为内核,系统调用,shell,公共函数库,应用程序。
在这里插入图片描述

三:登录
  登录用户信息一般存放在/etc/passwd下,passwd中存放了登录名、加密口令、数字用户ID(uid)、数字组ID(uid)、注释字段、起始目录、shell程序。shell程序是一个命令行解析器,他能读取用户的命令然后执行命令。

四:文件和目录
  UNIX文件系统是目录和文件的一种层次结构,所有文件的起点都是根目录,也叫root目录,这个目录的名称为 “/”
  我理解UNIX文件系统逻辑上呈现一颗树的的结构,这棵树中主要有两种节点,一个是叶子节点一个是非叶子节点,叶子节点都是文件,非叶子节点都是目录。也就是说目录其实是一个包含多个文件的一个节点。
  文件的名字称之为文件名,文件的名字不能包括左斜线和空格,但是一般来说文件名字最好是仅仅由以下几类字符组成的,包括字母、数字、点、短横线和下划线。
  值得注意的是,每个目录在创建的时候就包括了两个文件名 点(.)和点点(两个.),前者指向了目录本身,后者指向了父亲目录;root目录中的.和两个.都指向他自己。
  路径名称分为两种,绝对路径和相对路径,以左斜线为开头的是绝对路径,是从根目录开始查找,如果没有左斜线,从当前路径开始查找。
  比如当前路径为:/a/b 如果我们使用命令cd c/dcd /c/d 其中前者会让我们跳转到目录/a/b/c/d下,后者会让我们跳转到/c/d下
  用户在登入UNIX系统中后一般的起始目录就是他的工作目录,一般的工作目录格式为/usr/用户名字

五:输入和输出
  文件描述符一般是一个小的非负整数,用来标记一个特定进程访问的文件。
  每当运行一个新的程序时,shell都将会为其打开三个文件描述符,标准输入,标准输出,标准错误;如果不做特殊处理的话,这三个描述符都将指向终端。
  不带缓冲的IO有函数open、read、write、lseek、close;带缓冲区的IO也就是标准的IO有函数printf。
六:程序和进程
  程序就是一个可执行文件,内核使用exec函数来执行程序。
  程序执行的实例就是进程,也就是我们熟知的操作系统中的process,每一个进程都会有一个ID来标志,这个ID是一个非负整数。控制进程的函数主要有fork、exec、waitpid。
  通常情况下一个进程只有一个控制线程thread,但是一个进程是可以有多个线程的,而且多个线程也可以充分的利用多处理器系统的并行能力;同一个进程内的多个线程共享同一地址空间、文件描述符、栈以及进程相关的属性
  线程也有对应的ID来表示他们,但是线程的ID仅仅在他的所属进程内起作用
七:出错控制
  当UNIX系统函数出错的时候一般会返回一个负值,如果返回的是指针的函数一般会返回一个NULL指针
  出错分为两类,致命性的和非致命性的;如果是致命性的错误是无法执行回复动作的,如果是非致命性错误,一般可以妥善的处理,而且这种错误往往都是暂时的,比如资源短缺错误;他的典型回复方式就是等待一段时间然后重试。
八:用户标识
  对于登陆在UNIX系统中的用户,一般会有多个,对于每一个用户都会用一个用户ID来标识他,ID为0的用户为超级用户。
  一个用户不仅仅有用户ID(gid)还有组ID(uid)。有的用户还会有附属组ID,一般一个用户最多属于16个其他的组。
九:信号
  信号用于通知进程发生了某种情况,比如当一个进程要执行一个除数为0的除法的时候,就会给这这个进程发送一个浮点异常的信号(下图序号8)。进程有三种方式处理信号:
  1.忽略信号。
  2.按系统默认方式处理,比如浮点异常信号系统的默认处理方式就是终止这个进程。
  3.提供一个函数,信号发生时调用该函数,又被称为捕捉信号。
在这里插入图片描述
十:时间值
  UNIX系统中使用过两种不同的时间值:
  1.日历时间,该值是自1970年1月1日00:00:00以来国际标准时间(UTC)所经过的秒数累计值(早期的手册称UTC为格林尼治标准时间)。这些时间值用于记录文件最近一次的修改时间等。
  2.进程时间
  这也被称为CPU时间,用以度量进程使用的中央处理机资源。进程时间以时钟滴答计算,历史上曾经去每秒钟为50、60或100个滴答。
  系统基本数据类型clock_t用于保存这种时间值。可以使用sysconf函数得到每秒时钟滴答数。
  当度量一个进程的执行时间时,UNIX系统使用三个进程时间值:
  (1)时钟时间。
  (2)用户CPU时间。
  (3)系统CPU时间。
  有趣的是,在32位的操作系统中,日历时间所能记录的最大值转换为年是2038年,不过64位的操作系统中就不存在这个问题了。
十一:系统调用和库函数
  所有操作系统都提供多种服务的入口点,程序由此向内核请求服务。各种版本的UNIX实现都提供定义明确、数量有限、可直接进入内核的入口点,这些入口点被称为系统调用。系统调用实质上就是保存在内核中的函数。
  UNIX所使用的技术是将每一个系统调用在标准的C库中设置一个具有同样名字的函数,所以库函数中包括了所有的系统调用,但库函数中的函数并不都是系统调用。
  从实现者的角度观察,系统调用和库函数之间有重大的区别;但从用户角度来看,其区别并不非常重要。系统调用和库函数都以C函数的形式出现,两者都为应用程序提供服务。但是,我们应当理解,必要时我们可以替换库函数,而通常却不能替换系统调用。
  应用程序可以调用系统调用或者库函数,而很多库函数则会调用系统调用。
  系统调用和库函数之间的另一个差别是:系统调用通常提供一种最小接口,而库函数通常提供比较复杂的功能。

没有更多推荐了,返回首页