IO
- 文件IO和标准IO有什么区别?
- 文件IO
-
-
- 文件IO是由操作系统提供的基本IO函数,与操作系统绑定,又称之为系统调用
- 不同操作系统的文件IO函数是不一样的。
- 特点:
- 文件IO函数只能在相关的操作系统上使用,移植性比较低。
- 文件IO涉及到用户空间切换到内核空间,cpu模式的切换,C代码调用汇编指令等等,属于一种耗时操作,应该尽量减少对文件IO函数的使用。
- 如果要直接操作内核空间,则只能使用内核提供的函数接口,即只能使用文件IO函数。
-
2 标准IO
a 标准IO函数根据ANSI标准,对文件IO进行二次封装。scanf
b 标准IO函数最终依然会去调用对应操作系统的文件IO函数。
- 特殊的流指针有哪些?
- 标准输入流指针 FILE *stdin 可以通过stdin流指针从终端读取数据,scanf,getchar,gets内部使用的都是stdin流指针
- 标准输出流指针 FILE *stdout 可以通过stdout流指针向终端写数据,printf,putchar,puts内部使用的都是stdout流指针
- 标准错误输出流指针 FILE *stderr 可以通过stderr流指针向终端写数据,
- 缓冲区分类刷新方式?
- 全缓冲(手动用fopen函数打开文件时候,创建的缓冲区就是全缓冲。)
-
-
- 缓冲区满,溢出后会将缓冲中的4096个数据刷新出去
- fflush函数强制刷新缓冲区
- 关闭流指针 fclose
- 主函数调用return退出
- 调用exit函数退出程序
-
-
- 行缓冲(标准输入流指针(FILE *stdin) 标准输出流指针(FILE *stdout))
-
-
- 缓冲区满,溢出后会将缓冲中的1024个数据刷新出去
- fflush函数强制刷新缓冲区
- 关闭流指针 fclose
- 主函数调用return退出
- 调用exit函数退出程序
- 遇到'\n'字符刷新缓冲区
-
-
- 无缓冲
-
-
- 标准错误输出流指针(FILE *stderr); perror函数内部封装的就是stderr;
-
- 文件描述符的本质,总量,上限。
- 文件描述符的本质
-
-
- 文件描述符的本质是数组下标,该数组的容量默认为1024. 范围是[0, 1023]
- 文件描述符是有上限的,所以在不使用的情况下,需要关闭!!;
- 获取文件描述符的规则是,从小向大,依次获取,直到找到一个没有被使用的元素,返回该元素的下标。
- getdtablesize()函数,获取一个进程最多能打开几个文件描述符;
-
- 特殊的文件描述符。
- 其中有3个特殊的文件描述符,分别为0,1,2.
特殊的流指针(FILE *) | 特殊文件描述符(int) | |
FILE *stdin | 0 | stdin->_fileno |
FILE *stdout | 1 | stdout->_fileno |
FILE *stderr | 2 | stderr->_fileno |
进程
- 进程与程序的区别?
- 程序是静态的,存储在外存上的可执行二进制文件。
- 进程动态的概念,它是程序的一次执行过程,包括了进程的创建,调度,消亡,是存在内存中的。
- Linux中进程的调度方式?
- 进程是独立的,可以被调度的任务。
-
-
- Linux中的进程调度机制:时间片轮询机制
- 进程之间并发执行,cpu在多个进程之间根据时间片来回切换。
-
Linux中进程的5态图?
- 进程的内存分布:用户空间,内核空间特点,虚拟空间和物理空间的关系。4G是怎么来的。
- 虚拟内存空间和物理内存空间有---->映射关系
- 物理内存空间:内存条上(硬件上)真正存在的存储空间,
- 虚拟内存空间:程序运行后,会给每个进程分配4G虚拟内存空间。当要使用的时候,由物理地址映射到虚拟地址上使用
-
-
- 映射:可以理解为绑定,或者连接。
- 32位OS,虚拟地址空间为4G.
- 32位OS,指针变量占 4bytes,取值范围[0, 2^32-1],
- 指针变量只能存储[0, 2^32-1]范围内的地址。即只能存储[0, 4G-1]范围内的地址。即32位操作系统的指针变量寻址范围为4G个。
- 64位OS,虚拟地址空间为256TB
- 64位OS,指针变量占 8bytes,取值范围[0, 2^64-1],
- 由于虚拟地址的范围比较大,所以只使用了前48bit,[0,2^48-1]==>[0,256TB]
-
- 进程是资源分配的最小单位。
-
- 以进程为单位申请和释放内存空间
- 以进程为单位分配文件描述符:1024个
- 以进程为单位分配CPU时间片
- 以进程未单位管理自己的虚拟地址空间,在使用的时候由物理地址映射到虚拟地址上。
- fork函数
-
- 功能:创建一个子进程;
- 原型:
#include
#include
pid_t fork(void);
-
- 返回值:
成功, >0 在父进程中会返回新创建的子进程的PID号;
=0 在新创建的子进程中会返回0;
失败,返回-1,且没有子进程被创建,更新errno;
- 进程与进程之间有什么关系?父子进程之间有什么关系?
-
- 进程之间用户空间相互独立,(父子进程也是进程,所以也是相互独立)
- 子进程会拷贝父进程的用户空间资源,但是所映射的物理地址空间不一致。(写时拷贝)
-
- 父进程会将用户空间的资源拷贝一份给子进程。
- fork完毕的一瞬间,父子进程的用户空间的资源长得完全一致,但是用户空间不是同一块,因为进程之间的用户空间相互独立。
- 子进程会运行fork以下的代码,fork函数以及fork以上的代码是不执行的。
- 父子进程虚拟地址空间分布在拷贝完毕的时候完全一致,物理地址空间不一致
- 栈区、堆区、静态存储区、代码段均会拷贝一份给子进程;
- ps:写时拷贝:当fork完毕后,若父子进程只是读取对应内存空间的数据,不修改数据的情况下,其实父子进程虚拟地址空间映射到的物理地址空间是同一块。只有其中一个进程要修改内存空间中的数据时,此时会将父子进程的虚拟地址空间才会映射到不同的物理地址空间中。
- 父进程会将用户空间的资源拷贝一份给子进程。