1:冯诺依曼体系
我们常见的计算机都遵循着冯诺依曼体系。

我们认识的计算机,都是由一个个的硬件组成。
输入单元:鼠标,键盘,扫描仪等。
中央处理器(CPU):含有运算器和控制器等
输出单元:显示器,打印机等
关于冯诺依曼的几个点:
1:储存器指的是内存
2:不考虑缓存情况,这里的CPU只能对内存进行读写,不能访问外设
3:外设(输入输出设备)要输入和输出数据,只能写入内存或者从内存读取
4:所有设备只能和内存打交道
2:操作系统1(Operator System)
1:概念
任何计算机系统都包含一个基本的程序集合,称为操作系统。笼统的理解,操作系统包括:
内核(进程管理,内存管理,文件管理,驱动管理)
其他程序(库函数,shell程序等)

2:设计OS的目的
对下,与硬件交互,管理所有硬件资源
对上,为用户程序提供一个良好的执行环境

3:核心功能
在整个计算机软硬件架构中,OS定位是一款稿"管理"的软件
4:如何理解"管理"
1:描述起来,用struct结构体
2:组织起来,用链表或者其他高效数据结构
5:系统调用和库函数的概念
1:在开发角度,操作系统对外会表现成一个整体,但是会暴露自己的部分接口,供上层开发使用,这部分由操作系统提供的接口,叫做系统调用
2:系统调用在使用上,功能比较基础,对用户的要求也很高。所有,有心的开发者可以对部分系统调用进行封装,从而形成库,有了库,可以更加方便上层用户或者开发者进行二次开发
3:进程
1:基本概念和基本操作
课本概念:程序的一个执行实例,正在执行的程序等
内核观念:担当分配系统资源(CPU时间,内存)的实体
2:进行描述-PCB
1:基本概念
进程信息被放在一个叫做程序控制块的数据结构中,可以理解成进程属性的集合
课本上称为PCB(process control block),Linux下PCB是:task_struct
2:task_struct-PCB的一种
在Linux中描述进程的结构体叫做task_struct
task_struct是Linux内核中的一种数据结构,它会被装载到RAM(内存)里,并且包含进程的信息
3:task_struct
内容分类

组织进程

4:查看进程
1:进程的信息可以通过/proc系统文件夹查看
如:需要获取PID为1的进程信息,你需要查看/proc/1的文件夹

2:大多数进程信息同样可以用top和ps这些用户级工具获取

5:通过系统调用获取进程标识符
进程id(PID)
父进程id(PPID)
cpp
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
printf("pid: %d\n", getpid());
printf("ppid: %d\n", getppid());
return 0;
}
6:通过系统调用创建进程-初识fork函数
1:运行man fork认识fork
2:fork有两个返回值
3:父进程代码共享,数据各自开辟一个空间,私有一份(采用写时拷贝)
cpp
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
int ret = fork();
printf("hello proc : %d!, ret: %d\n", getpid(), ret);
sleep(1);
return 0;
}
fork之后一般需要使用if来分流
cpp
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
int ret = fork();
if(ret < 0){
perror("fork");
return 1;
}
else if(ret == 0){ //child
printf("I am child : %d!, ret: %d\n", getpid(), ret);
}
else{ //father
printf("I am father : %d!, ret: %d\n", getpid(), ret);
}
sleep(1);
return 0;
}
4:进程状态
1:查看Linux内核关于进程状态的源码
cpp
/*
*The task state array is a strange "bitmap" of
*reasons to sleep. Thus "running" is zero, and
*you can test for combinations of others with
*simple bit tests.
*/
static const char *const task_state_array[] = {
"R (running)", /*0 */
"S (sleeping)", /*1 */
"D (disk sleep)", /*2 */
"T (stopped)", /*4 */
"t (tracing stop)", /*8 */
"X (dead)", /*16 */
"Z (zombie)", /*32 */
};
R运⾏状态(running): 并不意味着进程⼀定在运⾏中,它表明进程要么是在运⾏中要么在运⾏
队列⾥。
S睡眠状态(sleeping): 意味着进程在等待事件完成(这⾥的睡眠有时候也叫做可中断睡眠
(interruptible sleep))。
D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个
状态的进程通常会等待IO的结束。
T停⽌状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停⽌(T)进程。这个被暂停的
进程可以通过发送 SIGCONT 信号让进程继续运⾏。
X死亡状态(dead):这个状态只是⼀个返回状态,你不会在任务列表⾥看到这个状态。
2:进程状态的查看
ps aux / ps axj
a:显⽰⼀个终端所有的进程,包括其他⽤⼾的进程。
x:显⽰没有控制终端的进程,例如后台运⾏的守护进程。
j:显⽰进程归属的进程组ID、会话ID、⽗进程ID,以及与作业控制相关的信息
u:以⽤⼾为中⼼的格式显⽰进程信息,提供进程的详细信息,如⽤⼾、CPU和内存使⽤情况等

3:僵尸进程
僵死状态(Zombies)是⼀个⽐较特殊的状态。当进程退出并且⽗进程(使⽤wait()系统调⽤,后
⾯讲)没有读取到⼦进程退出的返回代码时就会产⽣僵死(⼫)进程
僵死进程会以终⽌状态保持在进程表中,并且会⼀直在等待⽗进程读取退出状态代码。
所以,只要⼦进程退出,⽗进程还在运⾏,但⽗进程没有读取⼦进程状态,⼦进程进⼊Z状态
僵尸进程的危害
进程的退出状态必须被维持下去,因为他要告诉关⼼它的进程(⽗进程),你交给我的任务,我
办的怎么样了。可⽗进程如果⼀直不读取,那⼦进程就⼀直处于Z状态?是的!
维护退出状态本⾝就是要⽤数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,
换句话说,Z状态⼀直不退出,PCB⼀直都要维护?是的!
那⼀个⽗进程创建了很多⼦进程,就是不回收,是不是就会造成内存资源的浪费?是的!因为数
据结构对象本⾝就要占⽤内存,想想C中定义⼀个结构体变量(对象),是要在内存的某个位置
进⾏开辟空间!
内存泄漏。
4:孤儿进程
⽗进程如果提前退出,那么⼦进程后退出,进⼊Z之后,那该如何处理呢?
⽗进程先退出,⼦进程就称之为"孤⼉进程"
孤⼉进程被1号init进程领养,当然要有init进程回收喽
5:进程优先级
1:基本概念
cpu资源分配的先后顺序,就是指进程的优先权(priority)。
优先权⾼的进程有优先执⾏权利。配置进程优先权对多任务环境的linux很有⽤,可以改善系统性
能。
还可以把进程运⾏到指定的CPU上,这样⼀来,把不重要的进程安排到某个CPU,可以⼤ 改善
系统整体性能。
2:查看系统进程
在Linux下我们执行ps -l会出现这几个内容

3:进程的重要信息

4:查看进程优先级的命令
用top命令更改已存在进程的nice值
输入top命令->输入进程pid->输入nice值
6:进程切换
CPU上下⽂切换:其实际含义是任务切换, 或者CPU寄存器切换。当多任务内核决定运⾏另外的任务时, 它保存正在运⾏任务的当前状态, 也就是CPU寄存器中的全部内容。这些内容被保存在任务⾃⼰的堆栈中, ⼊栈⼯作完成后就把下⼀个将要运⾏的任务的当前状况从该任务的栈中重新装⼊CPU寄存器,并开始下⼀个任务的运⾏, 这⼀过程就是context switch。

7:Linux2.6内核进程O(1)调度队列
