目录
一. 文件描述符等
1. Linux下两个进程可以同时打开同一个文件,这时如下描述错误的是:
2. 以下关于标准输入输出错误的描述正确的是
3. 以下描述正确的是
4. 以下描述正确的是 [多选]
5. 在bash中,在一条命令后加入”1>&2”意味着()
6. 以下对int dup2(int oldfd, int newfd);接口描述错误的是: [多选]
7. 以下代码的功结果是
8. bash中,需要将脚本demo.sh的标准输出和标准错误输出重定向至文件demo.log,以下哪些用法是正确的 [多选]
9. 请简述你对文件描述符的理解(简答题)
10.请简述重定向的实现原理(简答题)
一. 答案及解析
二. inode和动静态库等
1. 下面关于Linux文件系统的inode描述错误的是:
2. 查看文件file的inode号,正确的是:
3. 使用In命令将生成了一个指向文件old的符号链接new,如果你将文件old删除,是否还能够访问文件中的数据?
4. Linux中包括两种链接:硬链接(Hard Link)和软连接(Soft Link),下列说法正确的是
5. 关于静态库与动态库的区别,以下说法错误的是()
6. 下面哪一个不是动态链接库的优点?
7. 关于动态库和静态库以下描述正确的有()
二. 答案及解析
本篇完。
A.两个进程中分别产生生成两个独立的fd
B.两个进程可以任意对文件进行读写操作,操作系统并不保证写的原子性
C.进程可以通过系统调用对文件加锁,从而实现对文件内容的保护
D.任何一个进程删除该文件时,另外一个进程会立即出现读写失败
E.两个进程可以分别读取文件的不同部分而不会相互影响
F.一个进程对文件长度和内容的修改另外一个进程可以立即感知
A.在文件描述符中0表示标准输出,1表示标准错误,2表示标准输入
B.在文件描述符中0表示标准错误,1表示标准输出,2表示标准输入
C.在文件描述符中0表示标准输入,1表示标准输出,2表示标准错误
D.在文件描述符中0表示标准输出,1表示标准输入,2表示标准错误
A.文件描述符和文件流指针没有任何关系
B.文件流指针结构中封装了文件描述符
C.通过open打开文件返回的FILE *fp可以直接使用read读取数据
D.通过open打开文件返回的FILE *fp可以直接使用fread读取数据
A.程序中打开文件所返回的文件描述符, 本质上在PCB中是文件描述符表的下标
B.多个文件描述符可以通过dup2函数进行重定向后操作同一个文件
C.在进程中多次打开同一个文件返回的文件描述符是一致的
D.文件流指针就是struct _IO_FILE结构体, 该结构体当中的int _fileno 保存的文件描述符, 是一对一的关系
A.标准输出重定向到标准错误输出
B.标准输入重定向到标准错误输出
C.标准输出重定向到标准输入
D.标准错误输出重定向到标准输入
A.重定向后,oldfd和newfd都会操作oldfd所操作的文件
B.重定向后,oldfd和newfd都会操作newfd所操作的文件
C.重定向前,若newfd已经有打开的文件,则会关闭
D.重定向前,若oldfd已经有打开的文件,则会关闭
void func()
{
int fd = open("./tmp.txt", O_RDWR|O_CREAT, 0664);
if (fd < 0)
{
return -1;
}
dup2(fd, 1);
printf("hello world");
return 0;
}
A.将hello wrold打印到终端显示
B.将hello wrold写入到tmp.txt中
C.将hello wrold打印到终端显示并且写入tmp.txt文件中
D.既不打印,也没有写入到文件中
A.bash demo.sh &>demo.log
B.bash demo.sh >&demo.log
C.bash demo.sh >demo.log 2>&1
D.bash demo.sh 2>demo.log 1>demo.log
1. D
在一个进程中打开一个文件,会在进程内生成文件的描述信息结构,并将其地址添加到pcb中的文件描述信息数组中,最终返回所在位置下标作为文件描述符
- A选项正确,进程数据独有,各自有各自的文件描述信息表,因此各自打开文件会有自己独立的描述信息添加在各自信息表的不同位置,因此fd各自也相互独立
- B选项正确,两个进程打开同一个文件,但是各有各的文件描述信息以及读写位置,互不影响,因此多个进程同时读写有可能会造成穿插覆盖的情况(原子性操作,被认为是一次性完成的操作,操作过程中间不会被打断,通常以此表示操作的安全性)
- C选项正确,文件锁就是用于保护对文件当前的操作不会被打断,就算时间片轮转,因为已经对文件加锁,其他的进程也无法对文件内容进行操作,从而保护在本次文件操作过程是安全的。
- D选项错误,删除文件实际上只是删除文件的目录项,文件的数据以及inode并不会立即被删除,因此若进程已经打开文件,文件被删除时,并不会影响进程的操作,因为进程已经具备文件的描述信息(可以编写代码进行尝试,在文件打开后,外界删除文件,然后看进程中是否还可以继续写入或读取数据)
- E选项正确,如果仅仅是读取文件内容,两个不同进程其实都有自己各自的描述信息和读写位置,因此可以同时读取文件数据而不会受到对方的影响。
- F选项正确,因为文件内容的修改是直接反馈至磁盘文件系统中的,因此当文件内容被修改,其他进程因为也是针对磁盘数据的操作,因此可以立即感知到(可以写代码尝试一个进程打开文件后,等其他进程修改了内容后然后再读取文件数据进行测试)
2. C
个进程启动后,默认会打开三个文件,分别针对,标准输入文件,标准输出文件,以及标准错误文件,而这三者文件分别对应的描述符为:
- 标准输入=0; 标准输入=1; 标准错误=2;
3. B
文件流指针是标准库IO操作句柄,是一个FILE*结构体指针,其中内部封装有文件描述符,其对应的操作接口有:fopen, fread, fwrite, fseek, fclose...
文件描述符是系统调用接口操作句柄,是一个非负整数,期对应的操作接口有: open, read, write, lseek, close...
根据以上理解:
- A选项错误,文件流指针中封装有文件描述符,他们是封装包含的关系
- B选项正确
- C和D选项错误,open是系统调用接口,返回的是文件描述符,并非文件流指针
4. ABD
- A选项正确:文件描述符实际上是内核中文件描述信息表中数组下标,用户根据下标在进程pcb中的文件描述信息表中找到相应文件描述信息,实现对文件的操作;
- B选项正确:不同信息表数组下标的位置可以存放相同的文件描述信息结构指针,dup2重定向的本质原理,就是改变对应位置的文件信息而改变操作对象文件的。
- C选项错误:文件描述符表中遵循最小未使用分配规则,也就是从表中找寻最小的没有被使用的位置进行存储,因此并不保证多次打开会使用同一个文件描述符
- D选项正确:我们见到的FILE *文件流指针,其实就是_IO_FILE的类型重定义,其中封装包含了文件描述符,因此一个文件流指针一定对应有一个文件描述符。
5. A
- 文件描述符中:0-标准输入;1-标准输出;2-标准输出;
- 在这条语句中,>是重定向符号 &2是在重定向使用时标准错误的一种特殊写法
- 因此 1>&2 被理解为: 将标准输出重定向到标准错误
6. BD
int dup2(int oldfd, int newfd); 函数功能为将newfd描述符重定向到oldfd描述符,相当于重定向完毕后都是操作oldfd所操作的文件 但是在过程中如果newfd本身已经有对应打开的文件信息,则会先关闭文件后再重定向(否则会资源泄露)
7. B
dup2(fd, 1);将标准输出,重定向到文件,这样则写往标准输出的数据会被写入到文件中,而不是被打印。
printf内部操作的是stdout标准输出文件流指针,而文件流指针本质上内部包含的是1号描述符成员。printf的打印就是向标准输出写入数据,因为标准输出已经被重定向,因此数据会被写入文件中,而不是直接打印
8. ABCD
在命令的重定向中, >表示冲定性,0表示标准输入,1表示标准输出,2表示标准错误
如果需要将标准输出和标准错误输出重定向至文件demo.log;
比较典型的方式是:bash demo.sh 1>demo.log 2>&1
- 先将标准输出重定向到demo.log文件,然后将标准错误重定向到标准输出(这时候的标准输出已经是指向文件了,所以也就是将标准错误重定向到文件)
A command &> file 表示将标准输出stdout和标准错误输出stderr重定向至指定的文件file中。
B 与A选项功能雷同
C 比较典型的写法,将标准输出和标准错误都重定向到文件, >demo.log是一种把前边的标准输出1忽略的写法
D 比较直观的一种写法,不秀技,直观的将标准输入和标准错误分别重定向到文件
9. 简述文件描述符的理解
自己写的:
在内核中,task_struct在自己的数据结构中包含了一个结构体指针,里面存在一个指针数组,指针数组里存放的是指向 struct file 的指针。fd就是这个指针数组的下标。fd的分配规则是从头遍历指针数组,找到一个最小的且没有被使用的下标分配给新的文件。
参考答案:
在进程中每打开一个文件,都会创建有相应的文件描述信息struct file,这个描述信息被添加在pcb的struct files_struct中,以数组的形式进行管理,随即向用户返回数组的下标作为文件描述符,用于操作文件
10. 简述重定向的实现原理
自己写的:
通过一定的方式调整文件描述符的内容,我们就可以完成重定向操作。dup2接口可以实现这个方式
参考答案:
每个文件描述符都是一个内核中文件描述信息数组的下标,对应有一个文件的描述信息用于操作文件,而重定向就是在不改变所操作的文件描述符的情况下,通过改变描述符对应的文件描述信息进而实现改变所操作的文件
A.inode和文件名是一一对应的
B.inode描述了文件大小和指向数据块的指针
C.通过inode可获得文件占用的块数
D.通过inode可实现文件的逻辑结构和物理结构的转换
A.ls -l file
B.ls -a file
C.ls -i file
D.ls -d file
A.不可能再访问
B.仍然可以访问
C.能否访问取决于文件的所有者
D.能否访问取决于文件的权限
A.软连接可以跨文件系统进行连接,硬链接不可以
B.当删除原文件的时候软连接文件仍然存在,且指向的内容不变
C.硬链接被删除,磁盘上的数据文件会同时被删除
D.硬链接会重新建立一个inode,软链接不会
A.加载动态库的程序运行速度相对较快
B.静态库会被添加为程序的一部分进行使用
C.动态库可用节省内存和磁盘空间
D.静态库重新编译,需要将应用程序重新编译
A.共享
B.装载速度快
C.开发模式好
D.减少页面交换
A.gcc test.c -o libmytest.so 命令可以生成一个动态库
B.库文件中可以包含main函数
C.静态库使用gcc命令生成
D.库文件的链接可以使用-L选项指定所在路径,使用-l命令链接指定的库文件
1. A
A选项错误,这里说的文件名指的是文件的目录项,一个文件inode是有可能有多个目录项的,比如给一个文件创建多个硬链接,因此并非一一对应
B选项正确,inode中包含了文件的各种描述信息,权限,大小,时间属性,数据块指针....等等都包含在内
C选项正确,inode中包含了文件数据所占据的存储位置的信息,因此可以获得we你按占用的数据块数
D选项正确,inode就像是文件的一个整体的描述,有了这个描述,上层就可以重新组织虚拟逻辑结构,通过inode映射其物理结构(简单理解可以联想类似于虚拟地址空间与物理内存之间的页表)
2. C
ls常见选项:
- -l 表示查看文件详细信息
- -a 表示查看所有包含以 . 开头的文件(隐藏文件)
- -i 打印每个文件的inode索引号
- -d 针对目录产生效果,表示查看目录文件自身信息,而并非目录内的文件信息
3. A
ln生成符号链接文件,指的是通过 ln -s 命令生成软链接文件,
软链接文件是一个独立的文件,有自己的inode节点,这个文件数据中保存的是源文件路径,通过保存的路径访问源文件,因此源文件被删除则无法再访问,通过路径将找不到源文件,这时候软链接就会失效。
4. A
软链接文件是一个独立的文件有自己的inode节点,文件中保存了源文件路径,通过数据中保存的源文件路径访问源文件
硬链接是文件的一个目录项,与源文件共用同一个inode节点,直接通过自己的inode节点访问源文件(其实本质上来说与源文件没区别)
- A正确 不同分区有可能有不同文件系统,就算系统相同,也会导致节点号有歧义冲突,因此硬链接不能跨分区建立,正确
- B错误 删除源文件,软链接文件失效
- C错误 硬链接被删除,则inode中的链接数-1,并不会直接删除文件数据,而是等链接数为0的时候才会实际删除对应文件的inode,将所占用数据块置为空闲
- D错误 硬链接与源文件共用inode
5. A
动态库也叫运行时库,是运行时加载的库,将库中数据加载到内存中后,每个使用了动态库的程序都要根据加载的起始位置计算内部函数以及变量地址,因此动态链接动态库加载及运行速度相较静态链接是较为不如的,但是它也有好处,就是多个程序在内存中只需要加载一份动态库就可以共享使用。
静态链接,链接静态库,每个程序将自己在库中用到的指令代码单独写入自己可执行程序中,程序运行时无依赖,加载运行速度快,但是程序运行后有可能会有冗余代码在内存中
根据以上理解分析:
- A错误 加载动态库的程序运行速度相对较慢,因为动态库运行时加载,映射到虚拟地址空间后需要重新根据映射起始地址计算函数/变量地址
- B正确
- C正确
- D正确 动态链接的程序一旦库中代码发生改变,重新加载一次动态库即可,但是静态链接代码是写入程序中的,因此库中代码发生改变,必须重新链接生成程序才可以
6. B
动态链接链接的是动态库,而动态库中包含了大量的常用的功能接口指令代码
这种链接方式,是用于解决静态库存在的浪费内存和磁盘空间,以及模块更新困难等问题。
动态链接生成可执行程序,可执行程序中会记录自己依赖的库列表以及库中的函数地址信息,等到运行程序的时候,由操作系统将库加载到内存中(多个程序可以共享,不需要加载多份相同实例),然后根据库加载后的地址在对每个程序内部用到的库函数的地址进行偏移计算。
基于这么一种思想,动态链接具有以下优缺点:
- 更加节省内存并减少页面交换;
- 库文件与程序文件独立,只要输出接口不变,更换库文件不会对程序文件造成任何影响,因而极大地提高了可维护性和可扩展性;
- 不同编程语言编写的程序只要按照函数调用约定就可以调用同一个库函数;
- 适用于大规模的软件开发,使开发过程独立、耦合度小,便于不同开发者和开发组织之间进行开发和测试。
- 运行时依赖,否则找不到库文件就会运行失败
- 运行加载速度相较静态库慢一些
- 需要对库版本之间的兼容性做出更多处理
7. D
A选项错误,默认情况下,gcc test.c -o libmytest.so 生成的是一个可执行程序,而并非动态库, 若要生成动态库需要使用 --shared 选项进行指定
B选项错误,库文件是被其他程序引入使用的,因此不能有main函数,否则会与程序中的main函数产生冲突
C选项错误,静态库使用 ar 指令生成
D选项正确,gcc的-L选项用于指定链接库路径, -l选项用于链接指定库文件
下一篇是进程地址通信的内容了,语言开始向C++转变,环境学用一下VSCode。
下一篇:零基础Linux_17(进程间通信)VSCode环境安装+进程间通信_pipe管道mkfifo。