手搓OS-day3

挺过了昨天的抽(硬)象(件)玩意,今天终于要迎来美丽的实战了(很能绷的住),下面我们要迎接大量的操作系统概念,虽然俺可能描述不清楚,但是我相信代码的力量,从现在要挑战编程能力惹。我尽可能拆开代码记录我的编程心路(阿门 worship)

架构

这里老师采用了一个分层的方式设计的架构,在硬件上通过一个Abstract Machine抽象出了部分API,这好处是显而易见的,就类似一个虚拟平台,对跨硬件是很有帮助的,显然Abstract的很多汇编我是不会写的,但是老师帮忙搭建好了(感恩)

简单架构

搓不动了,先放一放,研究一下设备无关编程(菜,哭)

断言的重要性

这个和我们在JAVA中接触过的单元测试有些相似,说他重要体现在快速定位错误(不是运行错误)的重要性上

断言基本用法:

1
2
3
#include <assert.h>

assert(bool exppression) //显然这里传入一个bool量,但想起int中0和非0分别代表false和true

使用场景:

  1. 在函数入口做合法性检查

  2. assert(0)放在绝对不会出现的地方

  3. 放在需要一些条件必须满足的地方

使用原则:

  1. 一个断言检查一个条件
  2. 断言不能代替if else
  3. 可以用开关条件编译打开或关闭断言,一般debug模式打开而在release模式下关闭。

Linux中proc文件中的进程

C语言文件操作

用一个FILE*的一个指针来指定一个FILE格式的结构体。

1
FILE *fp;
打开和关闭
1
2
3
4
FILE *fopen(const char *filename,const char *model);
// 文件名和打开参数
int fclose(FILE *stream);
// 传入指针
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main(){
//打开名为test.txt的文件,打开方式w为只读
FILE* pf = fopen("test.txt", "w"); //接收返回的文件信息区指针 (如果文件不存在,会自动创建)
//如果文件打开失败(例如文件不存在),会返回NULL
if (pf == NULL) {
perror("fopen\n");
return 1;
}
//关闭文件
fclose(pf);
//还需要将指针置空
pf = NULL;
return 0;
}
文件顺序读写

字符输入

1
2
3
4
fgetc('A',pf);
for (int i=0; i<26;i++){
fputc('a'+i,pf);
}

字符输出:

1
ch=fgetc(pf);

按行写入:

1
fputs("hello\n",pf)

按行读取:

1
2
char *arr;
fgets(arr,5,pf);

格式化输入:

1
fprintf(pf,"%s %d %f",s.name,s.age,s.height);

格式化读入:

1
fscanf(pf,"%s %d %f",s.name,&(s.age),&(s.height));

Linux Proc进程文件含义

  • comm:进程名
  • cwd:当前工作目录,是个软链接,指向实际的路径
  • environ:环境变量
  • exe:进程启动的二进制,也是个软链接,指向实际的文件路径
  • fd:进程打开的文件描述符,每个描述符也是个软链接,指向打开的文件,如果涉及到socket,则会显示socket的inode号 fdinfo/:进程打开文件时的一些属性
  • root:根路径
  • stat:进程的状态信息,包括ppid、进程名、进程启动时间等(这个是有用的)
  • status:进程的一些参数信息,包括uid、gid、虚拟内存、capability等
  • task/:进程的子线程,每个子目录就是一个线程的信息

其余见下链接

总结

嗯,今天编程的难度有点大,导致总结难产,主要看的内容也在参考链接里贴出来了,C语言好难(我好菜),明天预告maybe更难产

参考链接

Linux内核:进程管理——进程文件系统 /proc详解 - 知乎 (zhihu.com)

M1: 打印进程树 (pstree) (jyywiki.cn)

Linux学习之打印进程树_利用/proc进行进程树的打印-CSDN博客