CSDN 上的APUE读书笔记之第一章 -- Unix 基础

20 篇文章 0 订阅

1、Unix 手册页


Unix 参考手册页是进行系统编程必备的参考工具。它通常通过 man 命令直接联机阅读。手册页通常分为 9 节。采用“名称(章节号)”的方式来描述 Unix 术语时,表示此名称同时也是联机手册对应章节号下的一个条目。例如“fork(2)”指系统调用库函数 fork,可以使用“man 2 fork”来查看其手册页。

以 Linux 为例,参考手册页各节内容如下:

第 1 节为系统命令手册。如 cp(1);

第 2 节为系统调用手册。如 read(2);

第 3 节为库函数手册。如 malloc(3);

第 4 节为系统特殊文件手册。如 tty(4);

第 5 节为标准的系统资源文件(全局配置文件)手册。如 services(5);

第 6 节为游戏程序手册,包括屏保等各种图形化娱乐工具。如 glmatrix(6);

第 7 节为杂类手册,包括各类头文件和宏,如 socket.h(7);

第 8 节为系统管理工具,如 useradd(8);

第 9 节为内核例程。

工具apropos(1)可以用于查找手册页的名字和介绍;导入脚本/etc/bash_completion则可以增强 shell 的制表键自动补全功能,在输入man后列出手册页清单;还可以使用我写的一个比较山寨的索引工具。

重要的手册页软件包包括(包名因各 Unix 发行版而有所不同):manpages、manpages-dev、manpages-posix、manpages-posix-dev。


2、系统调用与库函数


系统调用提供了用户程序访问内核的接口,用户程序通过执行系统调用间接的获取内核所管理资源的访问权。执行系统调用时,程序控制权交给内核,内核在进程上下文中运行。

库函数通过包含相应的.h 头文件引用。用户程序可以通过调用操作系统提供的库函数间接进行系统调用。如 printf(3)库函数,它除了管理缓冲区和格式化文本之外,执行了 write 系统调用访问文件。库函数也可以由其它程序提供,例如 GTK库等。用户也可以自己重新实现库函数接口以替代所提供的库函数功能。

另一方面,系统调用实际上也以库函数的形式直接提供给用户程序,如 write(2)、fork(2)等。对用户程序来说,不必专门区别那些是库函数、哪些是系统调用接口。

对于 x86 平台的 Linux,亦可以通过/usr/include/asm/unistd_32.h查看其系统调用的接口。


3.文件和目录


Unix 系统将计算机中的大部分资源都抽象为文件的形式,这样我们就可以通过 open(2), read(2), write(2)等函数去直接访问它们。

  •  文件系统的结构:Unix 系统采用树状结构,全局具有唯一的一个根目录,通过“/”访问,除交换分区外,其它文件系统均挂载在/或其子目录下作为子目录存在。  
  • 文件名:除字符“/”与“NUL”外,都可以作为 Unix 文件的文件名,但为访问方便起见,一般建议采用可打印字符作为文件名,尽量不要使用shell 和其它正则表达式的扩展字符,如*、?等。 
  •  路径名:访问一个文件可使用绝对路径(以/开头)或者相对路径(不以“/”起头的均被认作相对路径)。 
  •  目录中的特殊文件“.”和“..”:“/”下的“.”“..”指向它自身,可以使用 shell 命令“ls -ai”验证这两个特殊文件的用法。 
  •  工作目录:每个进程都有一个当前工作目录(cwd, current working directory),用途为解释相对路径。
  • 起始目录(用户家目录 home directory):用户登录后的初始目录,由文件/etc/passwd 指定
4、输入和输出

  • 文件描述符(file descriptor):用以标识引用一个打开的文件,文件描述符是进程的属性。进程不同值相同的文件描述符引用的可以是不同的文件。  
  • 标准输入、标准输出和标准出错:进程创建时自动打开的三个文件描述符,默认为 0、1、2,一般通过用宏STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO 来引用。  不带缓冲的 I/O:标准系统调用 open(2)、read(2)、write(2)、lseek(2)、close(2)不使用缓冲区,直接把输入/输出送到内核,书中称为“不带缓冲的 I/O”。这里的缓冲位于进程地址空间;  
  • 标准 I/O:C 函数库中的标准 I/O 函数(定义在 stdio.h(7))使用缓冲区进行输入/输出、以提高吞吐效率。编程时要注意I/O 重定向及fork(2)导致复制地址空间等情况下标准I/O 函数对缓冲区的使用情况。

5、程序与进程

  •  程序是一个静态的概念,指存放在存储介质上可被内核通过 exec(3)系统调用读入并执行其中指令的文件,可能是二进制也可能是文本形式。Unix 上的程序需要执行权限。  
  • 进程是执行中的程序,除了程序本身的代码文本、数据外,进程还包括其它自身拥有的资源,诸如进程 id(PID)、打开的文件、地址空间、未决信号集、控制线程等。
6、程序线程
  • 对一个用户进程,内核实际执行调度处理的是它的执行线程。一个进程可以拥有一个或多个执行线程,对进程来说这些线程是并发执行的。进程内的多个线程共享进程资源。

7、异步、并发、通信

这几个术语也应该属于Unix 系统较重要的基本概念的一部分。书中没有用专门的章节进行描述,这里是一个补充。

  •  异步(Asynchronous)指的是对系统资源以不可预测的时间和顺序执行的操作。例如等待外部输入、监听TCP 端口等都是异步操作。对于异步操作,需要设计阻塞等待或超时等机制(一般都是基于信号机制实现)。  
  • 并发(Concurrency):多个并行的异步进程/线程同时在同一个资源上会合时,产生并发。这时由于各自的异步性,读写等I/O 操作可能交错发生乱序,从而出现意外的结果。为使它们的操作被强制的顺序化,需要进行同步处理)。同步处理属于广义上的通信的范畴,有多种同步方式,一般采用锁机制。同步处理还需要注意竞争条件出现的死锁。这是 Unix 系统编程中较为复杂、容易出现 bug 的地方。  
  • 通信(Communication):指通过某种机制,在不同实体间交换数据,对 Unix 编程来说,发送/接收、通知/响应、输入/输出等都属于比较广义的通信的范畴,狭义点的说法就指数据的发送/接收。Unix编程的主要通信方式为进程间通信和线程通信。广义的进程间通信包括了信号、管道、IPC对象、套接字。条件变量、取消等操作可以用作线程间的通信(通知)。建议性锁和全局变量也是一种通信机制。不同应用场合的通信使用不同的机制和做法。
8、出错处理
  • Unix 系统一般通过设置全局变量 errno(3)标识程序执行时发生的错误。在系统所提供的库函数中,除非再次发生错误,否则不会改动 errno 的值也不会将其清零。errno 可以通过下面两个函数转换为对应的错误消息字符串。

#include <string.h>
char *strerror(int errnum);
此函数将指定的errno 错误号转换为字符串并返回这个字符串的指针;

#include <stdio.h>
void perror(const char *msg);

此函数执行一个格式化输出,为指定的字符串+冒号+当前的errno 值对应的字符串。相当于执行了:

printf ("%s: %s", msg, strerror(errno));

9、Unix 用户和用户标识

  •   正常下,UID 唯一标识了一个用户; 
  •  系统的用户信息定义在/etc/passwd(passwd(5));  
  • 用户的创建、修改、删除通常由系统管理员通过 useradd(1)、userdel(1)、usermod(1)等系统命令执行,而不应直接修改/etc/passwd文件;  
  • 超级用户(root)的 UID 为 0;  
  • 组(group)将一个或多个用户组织起来,以使它们能以指定的相同权限访问资源;  
  • 正常下,GID 唯一标识了一个组;  GID 定义在/etc/group(group(5));  
  • 组的创建、修改、删除通常由系统管理员通过 groupadd(1)、groupdel(1)、groupmod(1)等系统命令执行,而不应直接修改/etc/group 文件; 
  • 用户可以同时加入多个组,命令 groups(1)可以打印出用户所在的组,第一个以外的均为附加组;

10、信号

  •  信号是软件中断机制,作为系统某种事件发生的通知;  
  • 进程可以通过调用信号函数,在信号递送到进程时选择对其的处理方式。对信号的处理有三种选择:忽略(丢弃)、按系统的默认方式处理、使用自定义信号捕捉函数来处理; 
  • 进程还可以选择在信号递送之前屏蔽之,使之成为未决信号而延后处理;  
  • 进程捕捉到信号时将被中断,直到信号处理函数返回时方恢复执行;

11、Unix 系统时间

系统使用两种方式标识时间:

  • 日历时间:指自 UTC 时间 1970 年 1 月 1 日 00:00:00 以来流逝的秒数,这个时间以 time_t 类型保存,这是一个32位整型数。在2038 年1月18日将发生溢出错误,例如,在Unix 系统上无法创建一个时间为 2038 年 1月以后的文件(touch -t命令)。目前业界尚未对此采取专门措施。
  • 进程时间。用以衡量进程资源耗时情况,包括实际时钟时间(real time,为一个进程执行开始至今的全部时间)、用户 CPU 时间(user time,为程序在用户地址空间中执行的时间)、系统 CPU 时间(system time,为程序执行系统调用后在内核空间中执行的时间)。另外如果进程执行了 sleep(3)等调用,睡眠的时间不计算为 CPU 时间,但计入实际时钟时间。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值