目录
【系统调用】
1.系统调用的概述
系统调用其实就是内核提供给用户的,操作Linux内核的函数接口。
那么为什么需要系统调用呢,答案是如果没有对Linux的系统内核保护,而是直接让用户直接去操作系统内核的话,是一个十分危险的行为,正是因为如此,官方才提供了系统调用这个东西,可以理解为,用户和系统内核中间的桥梁。
如下图所示,箭头指向的就是系统调用,外界想要调用内核只能通过系统调用。
2.系统调用和库函数的区别
系统调用是内核提供的,操作内核的接口。
库函数是第三方函数接口。
如果库函数想要操作系统内核,那么库函数需要调用系统调用。总之,想要操作系统内核只能通过系统调用(大概?)。
需要注意的是,系统调用可能会消耗系统大量的时间,如果频繁的调用系统调用的话。因为当执行系统调用的时候,CPU是工作在内核态的。意思就是执行系统调用,CPU会转向内核态。而想要转向内核态,需要先保存用户态的栈和内存环境,然后再转向内核态。而系统调用结束后,在转回用户态,十分消耗时间。
3.C中的IO函数工作流程
在C语言中的文件操作那一块内容,想要打开操作一个文件的话需要用到fopen等函数,而fopen函数会返回一个FILE* 类型的函数指针,很多刚接触到这里的人可能会对这个文件指针疑惑,不了解是怎么通过这个文件指针操作文件的。
FILE结构体解析(本人理解结合资料,不一定正确)
如下图所示
FILE是一个结构体,第一个是文件描述符,文件描述符是一个非负整数,每个进程都会有一个PCB(Process Control Block)来管理文件描述符,使用的是文件描述符表以位图的形式,在每个进程中,默认打开三个文件描述符,分别为0(标准输入文件),1(标准输出文件),2(标准错误输出),从3开始的就是用户打开的文件。
文件读写指针,通俗的来讲就是指向文件读取到的位置,三个函数用来控制这个指针。rewind复位流指针,ftell告诉距离文件首地址大小,fseek重定向文件流指针。
IO缓冲区,FILE结构体里面的文件缓冲区似乎是用来存储库函数写入,当缓冲区满了的时候,在调用系统调用。(存疑)
【文件描述符】
Linux中,将系统调用打开或者新建的文件用非负整数来表示,这个非负整数叫做文件描述符
系统会为每一个进程分配一个文件描述符表,管理该进程所有的文件描述符。
文件描述符表存放于内核空间(存储于PCB(进程管理块))
1.文件描述符表如何管理文件描述符
文件描述符表使用位图的方式来管理文件描述符,总共使用1024个二进制位来表示。1表示打开,0表示关闭。
系统默认打开的文件描述符
系统默认打开 0 1 2三个文件设备,默认 0 1 2 已经被使用
0位标准输入设备 键盘 scanf
1位标准输出设备 终端 printf
2为标准错误输出 终端 perror
如下图所示,默认没有打开其他文件的情况下,文件描述符表是这样的。
打开文件,文件描述符表操作
如果打开了文件,那么系统会默认为其分配最小并且可用的文件描述符作为此文件的文件描述符。