知识点1 【系统调用】
- 系统调用的概述
系统调用:内核 提供给 用户 可以 操作内核 的一组函数接口
关系:用户 借助 系统调用 操作内核
进程的空间分为:内核空间 和 用户空间
用户一般都是在用户空间操作的,但是有的时候用户需要获得系统服务,此时就要借助系统调用来实现这一目的
并且 系统调用 访问内核的路径都是内核安排好的,用户只能从特定的入口进入,也只能从特定的入口出内核,目的是为了保护内核的正常运行
- 系统调用和库函数的区别
这里我们从他们两个的定义 和关系来说明区别
定义
系统调用:由内核提供给用户的可以操作内核的一组函数接口
库函数:由第三方提供的函数接口
关系:库函数分为两种
- 调用 系统调用 的函数,如strcpy strlen
- 没有调用 系统调用 的函数,如fwrite fclose fopen
如果 库函数 没有调用 系统函数,那么该库函数不能够操作内核
大家请看下面这个图片
我们可以从上面这张图 知道分为内核态和用户态,运行在内核态的进程可以无限制的访问各种资源,毫无疑问,我们的系统调用就是属于内核态,但是它是如何从用户态切换到内核态的呢?
答案:通过软件中断,所谓软件中断就是通过软件指令出发的 并非外设(硬件)触发的中断。软件指令:编程人员开发中设置的一些 安全异常
系统调用的缺点
我们已经知道了系统调用的优点是可以提供给用户操作内核的一组函数接口,进而保护内核空间。那么缺点呢?
系统调用是需要时间的,频繁使用会降低程序的运行效率。当调用 系统调用 的时候,会进行连续的状态转换,这些状态转换会浪费许多时间
文件描述符
引入
我们都知道再Linux 中 万物皆可视为文件,那么我们该如何操作这些文件呢,这就需要 文件描述符
文件描述符的概述
Linux将 系统调用 打开或者新建的文件,用一个 非负整数 来表述。而这个 非负整数 就是 文件描述符。 对该文件的操作即是对该文件描述符的操作
系统默认打开的三个文件描述符:0,1,2
0:标准输入设备(键盘)
1:标准输出设备(终端)
2:标准输出设备(终端)
文件描述符表如何管理文件描述符
系统会为每个进程,都分配 文件描述符表,来管理该进程中的所有文件描述符
补充:文件描述符表 是在内核空间中存储的
那么,文件描述符表是如何管理文件描述符的呢?
答案:位图,也可以叫做二进制图形
我们可以将其理解为,图形化的数组,数组中存储的是一个二进制位。那么文件描述符就是数组的下标,数组中的内容就是文件的状态:1为打开状态,0为关闭状态。
并且 系统默认的位图最多可以存储 1024个二进制位。
下面我们总结一下
系统默认位图最大容量为1024个二进制位,位图的位数代表文件描述符,位上的内容代表文件的状态(1为打开,0为关闭)
大家请看我老师画的这张图:
我们该如何查看文件的文件描述符呢?
通过以上方式即可
ps -A 查看所有文件
grep 滤出 a.out 文件
此步骤可以 找到你的可执行文件的进程号
ls 即是通过进程好找到该进程的文件描述符
需要注意的是:
当打开文件的时候,默认会选择 最小可用的 文件描述符
更加深刻理解最小可用
如果你执行了
上面的操作 你有可能会出现下面这种情况:
当利用ls 执行后:
文件描述符为 1 3 2 19 20 4 5
不是说会选择最小可用吗 那为什么2会在3的后面呢?
这个问题 我遇到的时候也很疑惑,是为什么呢?
答案:在 1 2 3 后,关闭文件2,此时为1 3
如果这时打开文件,系统会为其分配最小可用的2文件描述符 这时的文件描述符 排列就为1 3 2
那为什么会忽然出现19呢
是因为4-18 正在被使用
而后面出现4 5 就和上面为什么会在3后面出现2 是一样的道理了。
相信你现在已经深刻理解了 文件描述符
总结
下面我们总结一下 今天的知识点:
- 系统调用的概述:
- 定义
- 与库函数的区别
- 系统调用的缺点
- 文件描述符
- 定义
- 文件描述符,文件描述符表,位图的关系
- 如何查询进程的文件描述符
- 你对最小可用的理解
结束
今天的内容就到此结束了,今天的内容大多篇概念类型,记忆内容较多,可能内容比较枯燥,但是我都加入了我的理解,已经尽可能的将抽象的内容变得形象。如果你有什么疑惑,可以评论留言,大家一起讨论。
最后,希望我的分享对你能够有所帮助,如果喜欢我的分享,请点赞收藏加关注,谢谢大家!!