Unix System Overview

Unix体系结构

Unix由内核、系统调用、shell外壳、库函数以及应用程序五部分组成
内核居于最中心,是整个Unix结构的核心,向上为应用进程提供系统服务,向下管理硬件资源
系统调用是内核提供给外部请求系统服务的入口,位于内核边界,外部若需要系统服务,必须使用系统调用进入内核态
库函数在系统调用之上,部分库函数不需要系统服务,部分库函数对系统调用的封装以实现可移植性
shell外壳是一个命令解释进程,与库函数同级,处理用户终端输入的命令
应用程序位于Unix体系的最上层,各个应用程序灵活的适用库函数和系统调用实现业务
图示:

img

库函数和系统调用关系图

以malloc为例子

在这里插入图片描述

登录

Unix适用多用户系统,当我们通过用户名+密码的方式进行登录时,系统会通过检查配置信息文件中的数据来验证用户合法性(保存用户信息的配置文件路径为**/etc/passwd**),该文件中有7个字段,分别是用户名、密码(加密显示)、用户ID、组ID、注释、家目录、shell程序

在这里插入图片描述

Linux示例,以用户admin为例,admin的用户ID和组ID号为1000,注释字段为空,家目录为/home/admin,当admin登录时系统会启动/bin/bash生成会话实现用户交互

文件和目录

文件系统

Unix文件系统是描述管理所有文件和目录的层状(树状)数据结构,可以叫做文件树,文件树的根节点是称为根目录(root),Unix下所有的文件和目录都在根目录之下,根目录用 ’ / ’ 来表示

广义上目录也是文件,只不过这个文件的数据是数个其他文件的属性信息(文件类型、文件大小、所有者、所属组、权限、和ACM时间)

文件名

文件名用户标识一个目录下的唯一文件(同一个目录下文件名是不允许重复的,不同目录下文件名可以重复),对于Unix来说文件名中不允许出现斜杠/和空格,POSIX.1标准推荐文件名只由字母、数字、下划线、短横线、点号组成

Unix中任何一个目录都会有2个固定的隐藏文件指示上一层目录和当前目录,其文件名为…和. ,对于根目录二者都指示当前目录

在这里插入图片描述

路径名

路径名是一串以斜杠作为分隔符的字符串,斜杠之间的字符串代表一个目录,用于文件树的搜索,路径名的最后一段字符串可能是目录也可能是普通文件(建议如果是目录则在路径名最后填上一个斜杠标识)

路径名分文绝对路径和相对路径

绝对路径固定以根目录为开始(/…)

相对路径常配合当前目录.和上一级目录…使用(./ or …/),对于路径不以./或…/开头的路径名,默认在当前目录开始查找

工作目录

每一个进程都有一个工作目录,工作目录又叫做当前工作目录,默认情况下进程所对应的程序文件位于的目录就是其工作目录,在程序中可以通过chdir系统调用改变进程工作目录

家目录

家目录为普通用户登录后显示的初始目录,用户的有关文件都存放在其家目录中,普通用户完全可以把家目录视作一个根目录,把所有的工作数据存在家目录下(这也是推荐的,不要干扰系统文件),家目录固定形式为/home/${user_name}

输入和输出

文件描述符

文件描述符fd通常是一个非负整数,是内核提供给进程访问特定文件资源的入口,当一个进程通过系统调用打开相应的文件时,如果成功打开,系统会返回给进程一个文件描述符,进程将文件描述符存储在其文件描述符表中,后续就可以通过文件描述符对文件进行读写操作(关于文件描述符的详细知识后续会谈到)

标准文件

标准文件指代标准输入、标准输出、标准错误,所对应的文件描述符分别问0、1、2,标准输入即键盘,接受键盘上输入的数据,标准输出和标准错误即显示器,将数据显示到显示器上

无缓冲IO(通用IO)

通用IO是Unix标准所提供的一系列文件读写系统调用,例如(open\read\write\lseek\close),这些接口适用于所有的Unix和类Unix操作系统,可以读写各种文件(网卡等硬件资源也被视作文件),这类系统调用都是不缓冲数据的,一旦调用马上进行

标准IO

标准IO一般有C标准库提供,是对通用IO的封装,具有可移植性强的特点,一般都有数据缓冲的特点,所谓数据缓冲就是当数据量到达一定条件时触发一次读写*(标准输出是行缓冲,标准错误没有缓冲,普通文件是页缓冲)*,缺点是不能像通用IO一样读取网卡这种抽象文件。

程序和进程

程序是存储在磁盘上的一个可执行文件,当程序被读入内存执行时就称作进程(有些书中叫做任务)

进程ID

Unix系统为每一个进程提供一个唯一的非负整数来标识进程,这个数称为进程ID(类似于人的身份证)

进程控制

当多进程相互配合完成一个作业时,需要进程之间的同步配合(进程不可以自管自了),因此需要通过一定的手段进行进程控制,Unix提供了三个基本系统调用来实现进程控制fork\exec\waitpid,分别为创建进程、执行程序、进程等待(具体后续文章给出)

线程

现代计算机CPU调度的最小单位为线程,一个进程可以有多个线程,线程之间共享同一块地址空间(栈和部分寄存器独占),线程通过并发执行大大提高CPU资源的利用率,并且由于线程共享地址空间,线程切换的成本远远小于进程切换的成本,线程也需要有线程ID进行唯一标识

出错处理

Unix的系统调用出现错误一般会返回-1或一个空指针指示,并且设置全局错误码,用户可以通过查阅相关文档来排查错误。使用错误码需要包含头文件<errno.h>,该头文件中声明了全局错误码变量和相关错误码描述

在这里插入图片描述

在这里插入图片描述

当错误发生时,可以通过库函数strerror和perror输出错误信息

char* strerror(int errnum);
void perror(const char* msg);

/*strerror通过传入的errnum可以返回其对应的错误描述
perror更加灵活,可以自动的在msg之后附加上错误信息(msg为用户自定义提示)*/

样例
在这里插入图片描述

这里为了方便显示设置errno,一般不会这么做,系统调用失败时会自动设置errno的值

错误恢复

错误恢复分为致命错误和非致命错误,对于致命错误来说基本上就是直接终止进程,对于非致命错误一般不会终止进程,而是选择暂时的忽略,隔一段时间后再次尝试系统调用。

信号

信号通常被用于通知进程某一个条件已经触发,进程在收到信号后需要采取必要的措施,常见的措施有三种

1、忽略信号

2、默认处理(一般都是终止进程)

3、自定义处理方法,当捕获信号时调用自定义函数进行处理

时间值

Unix提供2种时间类型,日期时间和进程时间

日期时间

日期时间就是日历,系统维护了一个名为时间戳的变量,这个变量标识从1970年1月1日0时至今的秒数,通过time函数可以获得时间戳,基于时间戳可以得到各种格式化的时间形式

进程时间

进程时间描述的是一个进程所占有CPU资源的时间(因此也叫做CPU时间),基本单位为一个时间节拍(clock tick),进程时间可以用来衡量一个算法的效率

可以通过time命令来获取一个可执行程序的用时
在这里插入图片描述

user和sys分别代表CPU在用户态和内核态下的进程时间,real为进程启动到退出的总用时(real不等于user和sys之和,在多进程环境下的等待时间也被算入real中,因此严格上将real的值不能叫进程时间),一个进程的进程时间(CPU时间)应该是user和sys的值之和。

原书中关于进程时间的描述,作参考

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shall#

你的鼓励将是我前进的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值