UNIX基础知识
一、UNIX 系统
-
UNIX内核的接口称之为系统调用。公用函数库构建在系统调用接口之上。应用程序既可以使用公用函数库,也可以使用系统调用。
-
UNIX shell 是一个特殊的应用程序,它为其他应用程序提供了一个接口。
-
路径名由斜线分隔的一个或者多个文件名组成的序列:
- 以斜线开头的路径名称为绝对路径名
- 以非斜线开头的路径名称为相对路径名
文件系统根的名字
/
是一个特殊的绝对路径名。它不包含任何其他的字符。 -
查看UNIX系统
ls
命令的man
帮助手册:man 1 ls
或者man -s1 ls
。1
表示第一部分。由于很多命令的说明文档过于庞大,因此 UNIX将说明文档划分成九个部分。常用的段有:1
: 可执行程序或者shell command
的说明2
: 系统调用的说明3
: 库函数的说明4
: 特殊文件(通常位于/dev/
)的说明8
: 系统管理员命令的说明(通常只有root
可用)
ls
表示shell command
,即待查找的目标
我们可以将 LINUX 操作系统中的
man
手册用中文的man
替代。方法为(UBUNTU操作系统下):sudo apt-get install manpages-zh sudo vi /etc/manpath.config
将
man
的配置文件/etc/manpath.config
中所有的/usr/share/man
替换为/usr/share/man/zh_CN
-
每个进程都有一个工作目录,有时称他为当前工作目录。所有的相对路径名都是从工作目录开始解释。
可以用
chdir
函数更改其工作目录 -
登录时,
shell
的工作目录设置为起始目录 -
UNIX系统中,每个进程都有一个唯一的数字标志符,称为进程ID(一个非负整数)。
-
通常一个进程只有一个线程。但是你也可以创建多个线程。
- 一个进程内的所有线程共享同一个地址空间、文件描述符、栈、进程相关属性
- 多线程的程序需要在各线程访问共享数据时采取措施来避免不一致性
- 线程也用ID标识,但是线程ID只有在它所属的进程内有意义
-
用户和组:
- 用户ID:标识各个不同的用户;用户ID为0的用户为根用户,其登录名为
root
,它具有超级用户权限。 - 组ID:用户所属的组的标识。
- 附属组ID: 一个用户可以属于多个组,这些组就是附属组。由附属组的ID来标识。
- 用户ID:标识各个不同的用户;用户ID为0的用户为根用户,其登录名为
二、错误处理
-
当 UNIX 系统函数出错时,通常会返回一个负值,同时整型变量
errno
通常被设置为具有特定信息的值。- 文件
<errno.h>
定义了errno
以及赋予它的各种常量,这些常量以E
字符开头 - 在多线程环境中,每个线程都有属于自己的局部
errno
,以避免一个线程干扰另一个线程。
对于
errno
的使用要注意两条规则:- 如果没有出错,则
errno
的值不会被清除.因此只有在函数的返回值指明出错了时,检查errno
才有意义 - 任何函数都不会将
errno
的值清零,且在<errno.h>
中定义的所有常量都不为0
- 文件
-
strerror/perror
函数:用于处理错误信息#include<string.h> char *strerror(int errnum); #include<stdio.h> void perror(const char*msg);
- strerror: 将
errnum
(通常就是errno
值)映射为一个出错消息字符串,并且返回此字符串的指针- 输入: 一个整数(通常是
errno
的值) - 输出: 出错消息字符串的指针(不需要用户手动分配出错消息字符串的内存)
- 输入: 一个整数(通常是
- perror: 基于
errno
的当前值,在标准错误上产生一条出错消息,然后返回。这条出错消息首先是msg
指向的字符串,后面是冒号,后面是一个空格,后面是对应于errno
值的出错消息,最后是一个换行符。- 输入:附加的出错消息
- 输出:无输出。但是向标准错误上输出一条出错消息,这条出错消息如上所述。
#include "apue.h" #include <error.h> int main(int argc, char *argv[]) { fprintf(stderr, "EACCES: %s\n",strerror(EACCES)); errno = ENOENT; perror(argv[0]); exit(0); }
- strerror: 将
-
出错恢复:可以将
<errno.h>
中定义的错误分成两类:- 致命性错误:此类错误无法恢复。最多只能在屏幕上打印一条出错消息或者将出错消息写入日志,然后退出。
- 非致命性错误:此类错误可以妥善处理。大多数非致命性错误时暂时的(比如资源短缺)
与资源相关的非致命性错误包括:
EAGAIN、ENFILE、ENOBUFS、ENOLCK、ENOSPC、EWOULDBLOCK
.其典型的处理方法是:延迟一段时间,然后重试。- 有时候
ENOMEM
也是非致命性出错 - 当
EBUSY
指明 共享资源正在使用是,也可视为非致命性出错处理 EINTR
中断一个慢速系统调用时,可以视为非致命性出错处理
三、时间
-
UNIX 系统使用两种时间:
- 日历时间:自 UTC 1970年1月1日 00:00:00 以来经历过的秒数累计值。用
time_t
数据类型来保存这种时间值。 - 进程时间:也称作CPU时间,用于度量进程使用的CPU资源。进程时间以时间滴答来计算,用
clock_t
数据类型保存这种时间值。
- 日历时间:自 UTC 1970年1月1日 00:00:00 以来经历过的秒数累计值。用
-
当度量一个进程的执行时间时,UNIX系统为一个进程维护了3个进程时间值:
- 时钟时间: 又称作墙上时钟时间,是进程运行的时间总量,其值与系统中同时运行的进程数有关
- 用户CPU时间:执行用户指令所用的时间量
- 系统CPU时间:该进程执行内核程序所经历的时间。如进程执行一个
read
系统调用,则内核执行该系统调用的时间计入系统 CPU 时间
用户CPU时间和系统CPU时间之和称作 CPU 时间
-
运行
shell
命令time
可以获取进程的时钟时间、用户时间和系统时间。time
的参数请参考man
手册