目录
1、冯诺依曼体系 ![](https://img-blog.csdnimg.cn/16c37c92d79b4cf48bf63a7926c0bebe.png)
输入设备:键盘、鼠标、扫描仪、写板等
中央处理器(cpu):含有运算器和控制器
输出单元:显示器、打印机等
注意
内储存器:指的是内存
不考虑缓存情况,这里的CPU能且只能对内存进行读写,不能访问外设(输入或输出设备)
外设(输入或输出设备)要输入或者输出数据,也只能写入内存或者从内存中读取。
所有设备只能直接和内存打交道
2、操作系统
2.1、概念
任何计算机系统都包含一个基本的程序集合,称为操作系统。
大概包括:
1、内核(进程管理、内存管理、文件管理、驱动管理)
2、其他程序
2.2、设计的目的
与硬件交互,管理所有的软硬件资源
为应用程序提供一个良好的执行环境
2.3、定位
这是一款纯正的“搞管理”的软件
3、进程
3.1、基本概念
程序的一个执行实例,正在执行的程序等,担当分配系统资源(CPU时间,内存)的实体。
3.2、描述进程-PCB
3.2.1、tack_struct——PCB的一种
在Linux中描述进程的结构体叫做task_struct。
task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息
3.2.2、task_struct内容分类
其他信息
3.3、组织进程
可以在内核源代码里找到它。所有运行在系统里的进程都以task_struct链表的形式存在内核里。
3.4、查看进程
进程的信息可以通过 /proc 系统文件夹查看
循环打印进程信息脚本:while :; do ps ajx | head -1 && ps ajx |grep 进程名 |grep -v grep; sleep 1; echo "################"; done
3.5、通过系统调用获取进程标识符
PID:进程id
PPID:父进程id
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
printf("pid: %d\n", getpid());
printf("ppid: %d\n", getppid());
return 0;
}
3.6、通过系统调用创建进程——fork初始
fork有两个返回值
父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝)
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
pid_t id=fork();
if(id==0)
{
printf("我是子进程,我的pid是:%d,我的父进程是:%d\n",getpid(),getppid());
sleep(1);
}
else
{
printf("我是父进程,我的pid是:%d,我的父进程是:%d\n",getpid(),getppid());
sleep(1);
}
return 0;
}
3.7、进程状态
R运行状态: 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。
S睡眠状态: 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠)。
D磁盘休眠状态:有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。
T停止状态: 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。
X死亡状态:这个状态只是一个返回状态,你不会在任务列表里看到这个状态
3.8、Z——僵尸状态
僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程没有读取到子进程退出的返回代码时就会产生僵死(尸)进程,僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。 所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态。
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
pid_t id=fork();
if(id==0)
{
int cnt=5;
while(cnt)
{
printf("我是子进程,我还剩下%d秒\n",cnt--);
sleep(1);
}
printf("我是子进程,我已经僵尸了,等待被检测\n");
exit(0);//子进程退出
}
else
{
while(1)//父进程一直循环
{
sleep(1);
}
}
return 0;
}
3.9、孤儿进程
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
pid_t id=fork();
if(id==0)
{
int cnt=5;
while(1)
{
printf("我是子进程,我还剩下%d秒\n",cnt--);
sleep(1);
}
exit(0);
}
else
{
int cnt=3;
while(cnt)
{
printf("我是父进程,我剩下%d秒",cnt--);
sleep(1);
}
exit(0);
}
return 0;
}
4、进程优先级
4.1、概念
cpu资源分配的先后顺序,就是指进程的优先权(priority)。
优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。
还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能。
4.2、查看系统进程 ![](https://img-blog.csdnimg.cn/f28e5314e81b4f0081ba6b31cf2aec15.png)
UID : 代表执行者的身份
PID : 代表这个进程的代号
PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
PRI :代表这个进程可被执行的优先级,其值越小越早被执行
NI :代表这个进程的nice值,其表示进程可被执行的优先级的修正数值
4.3、PRI和NI
PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为:PRI(new)=PRI(old)+nice,当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行。
调整进程优先级,在Linux下,就是调整进程nice值,nice其取值范围是-20至19,一共40个级别,进程的nice值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进程的优先级变化
4.4、 查看进程优先级的命令
输入top
进入top后按“r”–>输入进程PID–>输入nice值
4.5、其他
竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级
独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰
并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行
并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发
5、环境变量
5.1、概念
环境变量:一般是指在操作系统中用来指定操作系统运行环境的一些参数,如:在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性
5.2、常见环境变量
PATH : 指定命令的搜索路径
HOME : 指定用户的主工作目录
SHELL : 当前Shell,它的值通常是/bin/bash
5.3、和环境变量相关命令
1. echo: 显示某个环境变量值
2. export: 设置一个新的环境变量3. env: 显示所有环境变量4. unset: 清除环境变量5. set: 显示本地定义的shell变量和环境变量
5.4、环境变量组织方式
每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串
5.5、获取环境变量
5.5.1、命令行第三个参数
#include <stdio.h>
int main(int argc, char *argv[], char *env[])
{
int i = 0;
for(; env[i]; i++)
{
printf("%s\n", env[i]);
}
return 0;
}
5.5.2、通过第三方变量environ获取
#include <stdio.h>
int main(int argc, char *argv[])
{
extern char **environ;
int i = 0;
for(; environ[i]; i++)
{
printf("%s\n", environ[i]);
}
return 0;
}
//libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时 要用extern声明。
5.5.3、getenv
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("%s\n", getenv("PATH"));
return 0;
}
6、程序地址空间
我们在用C/C++语言所看到的地址,全部都是虚拟地址!物理地址,用户一概看不到,由OS统一管理OS必须负责将虚拟地址转化成物理地址
7、内核进程调度队列
一个CPU拥有一个runqueque
7.1、优先级
普通优先级:100~139
实时优先级:0~99