- 内核的接口被称为系统调用;
- 公用函数库构建在系统调用接口上,应用程序既可以使用公用函数库,也可以使用系统调用;
- shell是一个特殊的应用程序,为运行其他应用程序提供了一个接口;
第一章 UNIX基础知识 -
操作系统 = 内核 + 一些其他软件(系统实用程序、应用程序、shell 和 公用函数);
1) 实用程序:是针对操作系统的不足而 编制的程序,它帮助用户进一步管理好自己的计 算机;
2) shell:计算机用来解释你输入的命令然后决定进行何种处理的程序(也可以处理文件);
- 用户名和密码的信息都可以在 /etc/passwd 和 /etc/shadow 中找到;
-
UNIX系统中常见的shell:
1) Bourne shell
2) Bourne-again shell
3) C shell
4) Kom shell
5) TENEX shell
- 不同的Linux系统使用不同的默认shell;
- 目录 是一个包含目录项的文件,目录项是对该目录相关信息的说明;
- 在Linux中,“/” 和 “ ”不能出现在文件名中,原因是“/”用来分隔构成路径名的文件名,“ ”用来终止一个路径名;
- 创建新目录时会自动创建两个文件名:“.” 和 “…”,“.” 指向当前目录,“…” 指向父目录;
- 图1-3相关注释:
第一章 UNIX基础知识 另附👉struct dirent 和 DIR结构体 详解
另外,如果自己实现书中代码,需要安装 apue.h 库,网上可以搜到教程,这里不再赘述。推荐使用第三版,相对来说需要重新配置的地方比较少。
-
每个进程都有一个工作目录,进程可以用 chdir 函数更改其工作目录;
注:chdir 函数的参数是当前工作目录,返回值为 0 则说明修改成功。
- 文件描述符通常是一个小的非负整数,也就是内核打开或创建一个文件时的返回值,我们通过它来对该文件进行读写操作;
- 通常,当运行一个新程序时,shell为其打开3个文件描述符 ---- 标准输入、标准输出和标准错误;
- 函数 open、read、write、lseek、close 提供了不带缓冲的 I/O,它们都使用文件描述符;
- 图1-4相关注释:
第一章 UNIX基础知识 - 标准 I/O,也就是类似 printf 之类的函数,都提供了缓冲区,我们使用时无需考虑缓冲区大小的问题;
- 内核使用 exec 函数将程序读入内存并执行;
- 进程ID总是一个非负整数;
- 使用 getpid() 可以获得当前进程的进程 ID;
- 图1-7相关注释:
第一章 UNIX基础知识 -
进程控制的主要函数:
1) fork:创建一个新进程,返回值为子进程的进程ID;
2) exec:exec()族函数用一个新的进程映像替换当前进程映像;
3) waitpid:暂时停止目前进程的执行,直到有信号来到或子进程结束;
- 一个进程内的线程共享这个进程的资源,所以多线程进程需要采取同步措施(比如锁)避免不一致性(比如同时修改数据);
- 线程 ID 只在它所属的进程中有意义;
- errno 定义在 <errno.h> 中;
- 多线程情况下,每个线程都有属于它的局部 errno,以避免互相干扰;
-
errno 的使用规则:
1) 如果没有出错,其值不会被例程(例程是某个系统对外提供的功能接口或服务的集合,比如操作系统的API、服务等)清除,因此,仅当函数的返回值指明出错时,才检验其值;
2) 任何函数都不会将 errno 的值设为 0,而且在 <errno.h> 中定义的所有常量都不为0;
-
C 标准下的两个用于打印出错信息的函数:
1) strerror :将 errno 值映射为一个出错消息字符串,并且返回这个字符串的指针;
2) perror :基于 errno 的当前值,在标准错误上产生一条出错消息,然后返回;
- 图1-8 相关注释:
第一章 UNIX基础知识 -
两种出错:
1) 致命性的:在用户屏幕上打印出一条出错消息或将一条出错消息写入日志文件,然后退出;
2)非致命性的:有时可以较为妥善的处理,大多非致命出错是暂时的(如资源短缺)。对于资源相关的非致命性出错的典型恢复操作是延迟一段时间,然后重试;
- root 用户的用户 ID 为 0;
- 附属组:部分新的 unix 系统版本允许一个用户属于另外一些组;
-
终端键盘上有两种产生信号中断当前运行的进程的方法:
1) 中断键:Delete 或 Ctrl+C
2) 退出键:Ctrl+\
另一种产生信号的方式是调用 kill 函数,从一个进程向另一个进程发送信号;
- 图1-10新增代码相关注释:
第一章 UNIX基础知识 -
时间值:
1) 日历时间:time_t
2) 进程时间:clock_t
-
进程时间值:
1) 时钟时间:进程运行的时间总量;
2) 用户CPU时间:执行用户指令所用的时间量;
3) 系统CPU时间:为该进程执行内核程序所经历的时间;
- 系统调用:由操作系统提供的向内核请求服务的程序;
- 库函数虽然可能会调用一个或多个内核的系统调用,但它们并不是内核的入口点;
- 如果希望的话,我们可以替换库函数,但是系统调用通常是不可以被替换的;
- 应用程序既可以调用系统调用也可以调用库函数,很多库函数则会调用系统调用;
- 系统调用通常提供一种最小接口,而库函数通常提供比较复杂的功能。
课后习题百度文库有参考答案。