UNIX整理

匿名 (未验证) 提交于 2019-12-03 00:33:02

《UNIX程序设计》期末考试复习提纲

题型:

复习要点:

(1)什么是操作系统?什么是UNIX操作系统?什么是Linux操作系统?它们之间的关系是怎样的?

操作系统:控制计算机硬件和软件资源,对作业进行合理的调度,以供用户方便使用的一组软件的集合。

UNIX操作系统,是一个强大的多用户、多任务操作系统,支持多种处理器架构,按照操作系统的分类,属于分时操作系统

类Unix操作系统,是一个基于POSIXUNIX的多用户、多任务、支持多线程和多CPU的操作系统。

Linux继承了Unix网络为核心的设计思想,它能运行主要的UNIX工具软件、应用程序和网络协议。

(2)程序运行时,堆栈如何变化?什么是数据帧或活动记录?bp和sp指针在函数运行过程中是如何变化的?

新的栈中变量会在低地址的位置,新的堆中的变量会在高地址的位置

栈是向低地址延伸的,堆是向高地址延伸的

过程活动记录/栈帧,每个(用户)栈帧包括如下内容:

函数实参和局部变量:由于这些变量都是在调用函数时自动创建的,因此在C语言中称其为自动变量。函数返回时将自动销毁这些变量(因为栈帧会被释放),这也是自动变量和静态(以及全局)变量主要的语义区别:后者与函数执行无关,且长期存在。

函数调用的链接信息:每个函数都会用到一些CPU寄存器,比如程序计数器,其指向下一条将要执行的机器语言指令。每当一函数调用另一函数时,会在被调用函数的栈帧中保存这些寄存器的副本,以便函数返回时能为函数调用者将寄存器恢复原状。

SP:基址寄存器(stack pointer),一般在函数中用来保存进入函数时的sp的栈顶基址,出栈入栈操作时,

(3)UNIX环境下编程共同遵循的规范有哪些?“Least Surprise”是什么意思?

常见的标准共有三个:ISO C、POSIX、SUS。

ISO C:是C语言标准,是开发语言标准,与任何系统均无关。

POSIX:全写是Portable Operating System Interface。是操作系统的接口标准,在后期有包括ISO C这个C语言标准。

SUS:全写是Single Unix Specification。是POSIX.1的超集,定义了一些附加接口,扩展了POSIX.1这个标准。

POSIX.1中包含X/Open系统接口,是可选项。

X/Open系统接口可选项(X/Open System Interface),属于POSIX.1标准的一部分。描述了可选的接口,以及规定了遵循XSI(XSI Confirming)的实现,必须支持的POSIX.1的哪些可选部分。

只有遵循了XSI的实现才可以成为Unix。

Unix商标为Open Group所拥有。

Least Surprise是减少不必要的创新,减少用户学习成本

(4)常用的Shell命令,如ls、cd、dd、pwd、ps、cp、chown、chmod、mkdir、size等的具体用法。

该参数显示更详细的文件信息。

使用这个参数表示在文件的后面多添加表示文件类型的符号,例如*表示可执行,/表示目录,@表示连结文件,这都是因为使用了-F这个参数。但是现在基本上所有的Linux发行版本的ls都已经内建了-F参数,也就是说,不用输入这个参数,我们也能看到各种分辨符号。

cd(change directory) 用于切换用户当前工作目录

dd(disk dump)指定大小拷贝文件

pwd(print working directory)用于显示用户当前工作目录

(5)什么是管道?哪些文件参与了管道?在命令行下和通过编程如何实现管道?




(6)常规文件和目录文件的差别是什么?常规文件、目录文件、软链接文件的长度如何计算?

常规文件:最常用的文件类型,包含了某种形式的数据,存储普通数据,一般就是字符串。

只有内核可以直接写目录文件存储了一张表,该表就是该目录文件下,所有文件名和inode的映射关系。

(7)怎样移动文件?在命令行方式下和通过编程如何实现?

在命令行中,使用mv

mv file1 /dir2把file1移到根目录下的dir2目录下。
mv file1 /dir2/file2如果file2是目录,file1会被移入dir2/file2目录。

(8)怎样利用gcc编译源文件?gcc的-o、-e、-static、-Wall等选项的具体含义是什么?怎样使用?

(9)什么是动态链接库?什么是静态链接库?怎样用静态链接的方式编译C程序?

动态库(dynamic link library),后缀为”.so”,运行时链接。对一些库函数的链接载入推迟到程序运行时期文件大小较小,可移植性不强

静态库(static libaray),通常文件名为“libxxx.a”的形式,库函数编译期链接。对函数库的链接是放在编译时期(compile time)完成的。所有相关的对象文件(object file)与牵涉到的函数库(library)被链接合成一个可执行文件(executable file)。生成的可执行文件就不受库的影响了,即使库被删除了,程序依然可以成功运行。文件较大,但有良好的可移植性

(10)什么是文件系统?UNIX的文件系统有什么特点?有哪些具体的文件类型?

文件系统是操作系统用于明确存储设备(常见的是磁盘,也有基于NAND Flash的固态硬盘)或分区上的文件的方法和数据结构;即在存储设备上组织文件的方法。

Unix可以把一个能随机存取的存储介质(如:硬盘、软盘和光盘)上的存储空间划分成一致多个区域,每个区域都可以像独立的物理设备一样单独进行管理和数据存取,这样的存储区域,即是逻辑设备。在逻辑设备上按照一定的格式进行划分,就构成了逻辑文件系统,简称文件系统。

特点:UINX的文件是无结构的字符流文件

文件类型:

普通文件

目录文件

块特殊文件(block special file)提供对设备带缓冲的访问,每次访问以固定长度为单位进行

字符特殊文件(character special file)提供对设备不带缓冲的访问,每次访问长度可变。系统中所有设备要么是字符特殊文件,要么是块特殊文件

FIFO 用于进程间通信,有时也称为命名管道(named pipe)

套接字(socket)用于进程间的网络通信,套接字也可以用于在一台宿主机上进程之间的非网络通信

符号链接/软链接(symbolic link)这种类型的文件指向另一个文件

(11)什么是文件的访问权限?使用chmod命令怎样改变访问权限?chmod 0777是什么意思?

文件访问权限指文件是否可以被不同类型的用户访问的标识符

(12)什么是文件操作是的偏移量(offset)?它的数据类型是什么?操作系统中文件的最大长度取决于什么?

(13)什么是管道?什么是文件重定向?dup()、dup2()函数怎样使用?

UNIX操作系统进程间通信的一种方式,一个进程的输出直接传递到另一个进程作为输入

所有进程会在操作系统的进程表中占据一条记录,称为Process table entry,在其中会维护一个file descriptor table,每个整数会对应一个指针,指向在内核中被打开的文件记录。所谓文件重定向,是指某个文件描述符对应的指针,放弃指向原有的文件记录,而指向由其他文件描述符指向的文件记录。
例如,标准输出文件的描述符是1,如果将整数1对应的文件记录改为一个普通的文本文件,就可以实现将原本在控制台输出的内容写入文本文件的功能,这就是文件重定向。

二者都用来复制打开的文件描述符,复制成功后和复制源共享同一个文件表。

int dup (int filedes);

int dup2 (int filedes, int filedes2);

两函数的返回值:若成功则返回新的文件描述符,若出错则返回-1

由dup返回的新的文件描述符一定是当前可用文件描述符中的最小数值。用dup2则可以用filedes2参数指定新的描述符的数值。如果filedes2已经打开,则先将其关闭。若filedes等于filedes2,则dup2返回filedes,而不关闭它。

(14)什么是文件的静态属性和动态属性(文件描述符属性)?在文件描述符属性中,哪些是由进程维护的?哪些是由内核维护的?

内核使用三种数据结构表示打开的文件,分别是文件描述符表、文件表和 V 节点表。

(1) 每个进程在进程表中都有一个记录项,记录项中包含有一张打开文件描述符表,每个描述符占用一项。与每个文件描述符相关联的是:

(2) 内核为所有打开文件维持一张文件表。每个文件表项包含:

(3) 每个打开文件(或设备)都有一个 v 节点(v-node)结构。v 节点包含了文件类型和对此文件进行各种操作的函数的指针。v 节点还包含了从磁盘读取的 i 节点(i-node)的信息,i 节点信息包含了文件的所有者、文件长度、文件所在的设备、指向文件的实际数据块在磁盘上的所在位置的指针等。


(15)什么是会话(Session)、进程组?它们之间有什么关系?

进程组是一个或多个进程的集合,通常它们与一组作业相关联,可以接受来自同一终端的各种信号。每个进程组都有唯一的进程组ID(整数,也可以存放在pid_t类型中)。

会话是一个或多个进程组的集合。

每个进程组都有一个组长进程,组长进程的标识是进程组ID等于其进程ID。进程调用setsid函数创建一个新的会话,该进程会变成新会话的会话首进程,该进程也成为一个新进程组的组长进程。如果此调用进程已经是一个进程组的组长,则此函数返回出错。

(16)父进程和子进程之间是什么关系?怎样在父子进程之间共享文件描述符?

fork之后,操作系统会复制一个与父进程完全相同的子进程,虽说是父子关系,但是在操作系统看来,他们更像兄弟关系,这2个进程共享代码空间,但是数据空间是互相独立的,子进程数据空间中的内容是父进程的完整拷贝,指令指针也完全相同,子进程拥有父进程当前运行到的位置(两进程的程序计数器pc值相同,也就是说,子进程是从fork返回处开始执行的),但有一点不同,如果fork成功,子进程中fork的返回值是0,父进程中fork的返回值是子进程的进程号,如果fork不成功,父进程会返回错误。

1.进程的资格(真实(real)/有效(effective)/已保存(saved)用户号(UIDs)和组号(GIDs))

2.环境(environment)

3.堆栈

4.内存

5.打开文件的描述符(注意对应的文件的位置由父子进程共享,这会引起含糊情况)

6.执行时关闭(close-on-exec) 标志 (译者注:close-on-exec标志可通过fnctl()对文件描述符设置,POSIX.1要求所有目录流都必须在exec函数调用时关闭。更详细 说明,参见《UNIX环境高级编程》 W. R.Stevens, 1993, 尤晋元等译(以下简称《高级编程》), 3.13节和8.9节)

7.信号(signal)控制设定

8.nice值 (译者注:nice值由nice函数设定,该值表示进程的优先级,数值越小,优先级越高)

进程调度类别(scheduler class)(译者注:进程调度类别指进程在系统中被调度时所属的类别,不同类别有不同优先级,根据进程调度类别和nice值,进程调度程序可计算出每个进程的全局优先级(Global process prority),优先级高的进程优先执行)

8.进程组号

9.对话期ID(Session ID) (译者注:译文取自《高级编程》,指:进程所属的对话期(session)ID,一个对话期包括一个或多个进程组,更详细说明参见《高级编程》9.5节)

10.当前工作目录

11.根目录 (译者注:根目录不一定是“/”,它可由chroot函数改变)

12.文件方式创建屏蔽字(file modecreation mask (umask))(译者注:译文取自《高级编程》,指:创建新文件的缺省屏蔽字)

13.资源限制

14.控制终端

子进程所独有:

进程号

1.不同的父进程号(译者注:即子进程的父进程号与父进程的父进程号不同,父进程号可由getppid函数得到)

2.自己的文件描述符和目录流的拷贝(译者注:目录流由opendir函数创建,因其为顺序读取,顾称“目录流”)

3.子进程不继承父进程的进程,正文(text), 数据和其它锁定内存(memorylocks)(译者注:锁定内存指被锁定的虚拟内存页,锁定后,

4.不允许内核将其在必要时换出(pageout),详细说明参见《The GNU C Library Reference Manual》 2.2版, 1999,3.4.2节)

5.在tms结构中的系统时间(译者注:tms结构可由times函数获得,它保存四个数据用于记录进程使用中央处理器 (CPU:Central Processing Unit)的时间,包括:用户时间,系统时间, 用户各子进程合计时间,系统各子进程合计时间)

6.资源使用(resourceutilizations)设定为0

8.阻塞信号集初始化为空集(译者注:原文此处不明确,译文根据fork函数手册页稍做修改)

9.不继承由timer_create函数创建的计时器

10.不继承异步输入和输出

(17)在一个进程中,文件描述符的增长规律是怎样的?例如,如果已经有0、1、2、6这样几个文件描述符,那么用open()返回的下一个文件描述符是什么?

由open和openat函数返回的文件描述符一定是最小的未用描述符数值。3。

(18)什么是process id?父进程和子进程的pid之间有什么关系?(通常子进程的pid要大于父进程的pid)

进程标识符,unix系统中用来唯一标识每个进程,是一个非负整数。

子进程总是可以调用getppid来获得父进程的pid,父进程在调用fork函数时可以获得子进程的pid.

(19)什么是C语言程序的入口函数?在C Startup Routine(start.S)中接受的main函数原型是什么?

Main函数。(当内核执行C程序时,在调用main前先调用一个特殊的启动例程,可执行程序文件将此启动例程设置为程序的起始地址。启动例程从内核取得命令行参数和环境变量值,然后为按上述方式调用main函数做好安排。)

Int main(int argc, char * argv[1]),argc是命令行参数的数目,argv是指向参数的各个指针所构成的数组。

(20)什么是系统调用?什么是C语言库函数?它们之间有什么区别和联系?

系统调用(英语:system call),指运行在用户空间应用程序操作系统内核操作系统之间的接口。一般来说,系统调用都在内核态执行。由于系统调用不考虑平台差异性,由内核直接提供,因而移植性较差(几乎无移植性)。

库函数(library function),是由用户或组织自己开发的,具有一定功能的函数集合,一般具有较好平台移植性,通过库文件(静态库或动态库)向程序员提供功能性调用。程序员无需关心平台差异,由库来屏蔽平台差异性。

一般而言,跟内核功能与操作系统特性紧密相关的服务,由系统调用提供;

具有共通特性的功能一般需要较好的平台移植性,故而由库函数提供。

库函数与系统调用在功能上相互补充,如进程间通信资源的管理,进程控制等功能与平台特性和内核息息相关,必须由系统调用来实现。

(21)什么是inode?里面存放什么信息?文件的文件名存放在哪里?

inode(index node)就是索引节点,它用来存放档案及目录的基本信息,包含时间、档名、使用者及群组等。inode信息就存储在磁盘的某个分区上

inode 内容

inode 包含文件的元信息,具体来说有以下内容:

* 文件的字节数

* 文件拥有者的 User ID

* 文件的 Group ID

* 文件的读、写、执行权限

* 文件的时间戳,共有三个:ctime 指 inode 上一次变动的时间,mtime指文件内容上一 次变动的时间,atime指文件上一次打开的时间。

* 链接数,即有多少文件名指向这个 inode

* 文件数据 block 的位置

可以用 stat 命令,查看某个文件的 inode 信息: stat example.txt 总之,除了文件名以外的所有文件信息,都存在 inode 之中。

(22)C程序的内存布局是怎样的?从低地址到高地址依次存放哪些段?

正文段:由CPU执行的机器指令部分。

初始化数据段:程序中需明确地赋初值的变量。

非初始化数据段:在程序开始执行之前,内核将此段中的数据初始化为0或空指针。

栈:自动变量以及每次函数调用时所需保存的信息都存放在此段中。

堆:通常在堆中进行动态存储分配。

从低地址到高地址依次存放正文,初始化的数据,未初始化的数据(bss),堆,栈。


(23)怎样利用fork()、exec()、waitpid()来创建和控制进程?

1.fork 函数调用一次,但返回两次。两次返回的唯一区别是:子进程返回值为 0,而父进程的返回值是新子进程的进程 ID。fork 函数返回之后,子进程和父进程都各自继续执行 fork 调用之后的指令。子进程是父进程的副本。例如,子进程获得了父进程数据空间、堆和栈的副本。

2.当进程调用一种 exec 函数时,该进程执行的程序完全替换为新程序,而新程序则从其 main 函数开始执行。调用 exec 并没有创建新进程,所以进程 ID 没有改变,exec 只是用一个新的程序替换了当前进程的正文、数据、堆和栈段。

3. waitpid 函数通过 pid 参数来控制父进程希望获取特定进程的终止状态信息,

waitpid 函数返回终止子进程的进程 ID。如果指定的进程或进程组不存在,或者参数 pid 指定的进程不是调用进程的子进程则都将出错。

(24)什么是孤儿进程、什么是僵尸进程?它们有什么特点?怎样避免产生过多僵尸进程?

孤儿进程:在其父进程执行完成或被终止后仍继续运行的一类进程。这些孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

僵尸进程:在UNIX术语中,一个已经终止、但是其父进程尚未对其进行善后处理(获取终止子进程的有关信息、释放它仍占用的资源)的进程。

1.终止进程的父进程调用wait和waitpid

2.两次调用fork()来使新创建的子进程变成孤儿进程,从而直接被1号进程收养。

(25)什么是前台进程?什么是后台进程?一个会话有几个前台进程组和几个后台进程组?

前台进程:用户使用的有控制终端的进程。

后台进程:也称守护进程,是运行在后台的一种特殊进程。独立于控制终端并且周期性地执行某种任务或者等待处理某些发生的事件。

一个会话中包含一个前台进程组,一个或多个后台进程组。

(26)C程序如何退出并返回操作系统?exit()函数和_exit()/_Exit()函数的差别在哪里?

进程的终止方式有 8 种,其中 5 种为正常终止,它们是

1. 从 main 返回。

2. 调用 exit。

3. 调用_exit 或_Exit。

4. 最后一个线程从其启动例程返回。

5. 最后一个线程调用pthread_exit。

另外三种为异常终止方式,它们是

1. 调用 abort。

2. 接到一个信号并终止。

3. 最后一个线程对取消请求做出响应。

这三个函数用于正常终止一个程序:_exit 和_Exit 立即进入内核,exit 则先执行一些清理处理(包括调用执行各终止处理程序,关闭所有标准 I/O 流等),然后进入内核。

(27)exec函数族包含哪些具体的函数?其中execve是系统调用,其它都是普通函数。

UNIX 提供了 6 种不同的 exec 函数供我们使用。它们的原型如下所示,

#include <unistd.h>
int execl(const char *pathname, const char *arg0, ... /* (char *)0 */);
int execv(const char *pathname, char *const argv[]);
int execle(const char *pathname, const char *arg0, ... /* (char *)0, char*const envp[] */);
int execve(const char *pathname, char *const argv[], char *const envp[]);
int execlp(const char *filename, const char *arg0, ... /* (char *)0 */);
int execvp(cosnt char *filename, char *const argv[]);
6个函数的返回值:若出错则返回-1,若成功则没有返回值

可能很多人会觉得这六个函数太难记了。但是,我们仔细观察会发现,这六个函数的命名是有一些规律的。

(28)什么是信号?SIGINT、SIGSTOP、SIGHUP、SIGALARM、SIGQUIT等信号是如何产生的?缺省的处理动作是什么?

在计算机科学中,信号是 Unix、类 Unix 以及其他 POSIX 兼容的操作系统中进程间通讯的一种有限制的方式。它是一种异步的通知机制,用来提醒进程一个事件已经发生。当一个信号发送给一个进程,操作系统中断了进程正常的控制流程,此时,任何非原子操作都将被中断。如果进程定义了信号的处理函数,那么它将被执行,否则就执行默认的处理函数。

SIGALRM 是闹钟信号,当由 alarm 函数设置的计时器超时后产生此信号。进程的信号屏蔽字复原为调用信号处理屏蔽字之前。

SIGQUIT,当用户在终端上按退出键(一般是Ctrl+\)时,中断驱动程序产生此信号,并发送给前台进程组中的所有进程。

SIGSTOP,作业控制信号,用以停止一个进程,当用户在终端上按挂起键(一般是Ctrl+Z)时,终端驱动程序产生此信号。

SIGHUP,如果终端接口检测到一个连接断开,则将此信号送给与该终端相关的控制进程(会话首进程)。

SIGINT,当用户按中断键(一般是Delete或Ctrl+C)时,终端驱动程序产生此信号并发送至前台进程组中的每一个进程。

(29)什么是硬链接和软链接(符号链接)?读取软连接的函数是什么?(readlink)

硬链接:通过 i 节点链接使多个目录项指向同一个文件的这种链接类型。

符号链接:对一个文件的间接指针,一般用于将一个文件或整个目录结构移到文件系统中的另一个位置。

readlink 函数打开符号链接本身,并读取该链接中的内容(不是该链接所引用的文件的内容)。

(#include <unistd.h>

ssize_t readlink(const char *restrictpathname, char *restrict buf, size_t bufsize);

返回值:若成功则返回读到的字节数,若出错则返回-1。

如果此函数成功执行,则返回读入 buf 的字节数。在 buf 中返回的符号链接的内容不以 null 字符终止。)

(30)函数link()和unlink()的作用是什么?什么时候文件占用的磁盘空间才会真正被释放掉?(两个条件)

Link():创建一个指向现有文件的链接;unlink删除一个现有的目录项。

打开文件的进程个数为0;

文件的链接计数为0。

(31)什么是可重入函数?怎样判断一个函数是不是可重入函数?

可重入函数主要用于多任务环境中,一个可重入的函数简单来说就是可以被中断的函数,也就是说,可以在这个函数执行的任何时刻中断它,转入OS调度下去执行另外一段代码,而返回控制时不会出现什么错误。

(也可以这样理解,重入即表示重复进入,首先它意味着这个函数可以被中断,其次意味着它除了使用自己栈上的变量以外不依赖于任何环境(包括static),这样的函数就是purecode(纯代码)可重入,可以允许有该函数的多个副本在运行,由于它们使用的是分离的栈,所以不会互相干。)

可以被多个任务调用的过程,任务在调用时数据不会出错,输入数据相同就应产生相同的输出。

(32)什么是带缓冲的输出和不带缓冲的输出?当父进程的输出缓冲区还未清空时,调用fork创建子进程,会出现什么情况?

不带缓冲的输出:在用户的进程中对这这类的函数不会自动缓冲,每次执行就要进行一次系统调用,针对文件描述符操作。

带缓冲的输出:在系统调用的上一层多加了一个缓冲区,针对流来操作。

如果标准输出连接到终端设备,则它是行缓冲的,否则它是全缓冲的。即以交互方式运行时,只得到父进程中printf输出的行一次,原因是标准输出缓冲区由换行符冲洗。但是当将标准输出重定向到一个文件时,却得到printf输出两次,原因是在fork之前调用了一次printf,但当调用fork时,该行数据仍在缓冲区中,然后在将父进程数据空间复制到子进程中时,该缓冲区数据也被复制到子进程中,此时父进程和子进程各自有了该行内容的缓冲区。

(33)编程的题目在这次考试中占很大的比重。一共有两道编程的题目。第一道跟文件操作相关,要求详细掌握的用法包括:能用open,read,write,close等函数来操纵文件;能利用lseek来形成文件中的“空洞”;能动态申请和释放空间等。

(34)第二道编程的题目跟进程和信号相关。要求详细掌握的用法包括:能用pause函数阻塞进程;能用signal设置信号处理函数;能向特定进程发送信号;能用rename移动文件;能遍历目录;能用S_ISREG宏辨别文件类型等等。切记对最后两道编程的大题要提前做好准备。

文章来源: UNIX整理
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!