Linux:进程概念详解
1. 冯诺依曼体系结构
截至目前,我们所认识的计算机,都是有一个个的硬件组件组成 。
【注意】:
a. 这里的存储器指的是内存
b. 不考虑缓存情况,这里的CPU能且只能对内存进行读写,不能访问外设(输入或输出设备)
c.外设(输入或输出设备)要输入或者输出数据,也只能写入内存或者从内存中读取。
d. 一句话,所有设备都只能直接和内存打交道。
冯诺依曼体系结构计算机的基本原理是?
答:计算机就是为了完成指定的数据处理,而通过指令按指定流程完成指定功能,指令的合集就是一段程序。说白了计算机就是按照指定的指令执行流程完成对指定数据的处理。
2. 操作系统(Operator System)
--------------------先描述,再组织!--------------------
先描述问题再用特定的数据结构组织起来!!!
1. 概念
任何计算机系统都包含一个基本的程序集合,称为操作系统(OS)。笼统的理解,操作系统包括:
a. 内核(进程管理,内存管理,文件管理,驱动管理)
b . 其他程序(例如函数库,shell程序等等)
2. 设计OS的目的
为什么要有操作系统?
答:操作系统对下(手段)进行软硬件管理工作,对上层提供良好(高效、稳定、安全)的运行环境(目的)!!!!!
3. 任务 (定位)
承担管理任务的软件!
4. 理解管理
系统调用和库函数概念
a. 在开发角度,操作系统对外会表现为一个整体,但是会暴露自己的部分接口,供上层开发使用,这部分由操作系统提供的接口,叫做系统调用。
b. 系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以,有心的开发者可以对部分系统调用进行适度封装,从而形成库,有了库,就很有利于更上层用户或者开发者进行二次开发。
3. 进程
---------- 进程 = PCB(task_struct) + 程序的代码和数据 ! ! ! ----------
1. 基本概念
a. 课本概念:程序的一个执行实例,正在执行的程序等
b. 内核观点:担当分配系统资源(CPU时间,内存)的实体。
2. 描述进程-PCB
a. 进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。
b. 课本上称之为PCB(process control block),Linux操作系统下的PCB是:task_structtask_structhttps://www.cnblogs.com/tongyan2/p/5544887.html
task_struct-PCB的一种
a. 在Linux中描述进程的结构体叫做task_struct。
b. task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息。
task_ struct内容分类
标示符: 描述本进程的唯一标示符,用来区别其他进程。 |
状态: 任务状态,退出代码,退出信号等。 |
优先级: 相对于其他进程的优先级。 |
程序计数器: 程序中即将被执行的下一条指令的地址。 |
内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针 |
上下文数据: 进程执行时处理器的寄存器中的数据。 |
I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。 |
记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。 |
<linux/sched.h>
struct task_struct {volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */void *stack;atomic_t usage;unsigned int flags; /* per process flags, defined below */unsigned int ptrace;int lock_depth; /* BKL lock depth */......
通过系统调用获取进程标示符
(每个进程都有自己唯一的标识符)
a: 进程id(PID)
b: 父进程id(PPID)
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
printf("pid: %d\n", getpid());
printf("ppid: %d\n", getppid());
return 0;
}
查看进程
进程的信息可以通过 /proc 系统文件夹查看
3. 进程状态
Linux内核源代码解释:
/*
* 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):这个状态只是一个返回状态,你不会在任务列表里看到这个状态。 |
进程状态转换
阻塞和运行的变化,往往伴随着PCB被连入不同的队列中!入队列不是进程的代码和数据,而是进程的task_struct。
进程切换
进程在切换之前,最重要的一件事:上下文数据的保护和恢复。
程序的上下文:CPU内部的所有寄存器中的临时数据。
CPU内的寄存器:寄存器本身是硬件,具有数据存储的能力,CPU寄存器硬件只有一套。
CPU内部的数据:CPU内部的数据可以有多套,有几个进程,就有几套和该进程对应的上下文数据。
4. 进程状态查看
ps aux / ps axj 命令
循环查看指定进程:
while :; do ps axj | head -1 && ps axj | grep XXXXX | grep -v grep;sleep 1;done
4. 创建进程 fork
fork调用很简单,但是要理解fork还是有点绕的!
fork之后:创建一个进程,多了一个进程,就是多了一个内核task_struct,自己的代码和数据。
父进程的数据和代码是从磁盘加载进来的,默认情况下子进程的代码和数据是继承父进程的。
是不是很奇怪?为什么fork的返回值 id==0 又 id!=0 ?返回两次? 先看一下手册怎么说?
原因:进程要做到独立性,父子要各自独立,原则上数据要相互分开! 父进程得到return id==子进程的id 父进程拿到id可能要对子进程做管理,子进程得到return id = 0子进程通过 fork()
返回的 0 来识别自己。
5. (Zombie)-僵尸进程
直接在命令行启动的进程,他的父进程是bash,bash会自动回收新进程的z。
a. 僵死状态(Zombies)是一个比较特殊的状态。
当进程退出并且父进程(使用wait()系统调用,后面讲)没有读取到子进程退出的返回代码时就会产生僵死(尸)进程。
b. 僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。
c. 所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态
//测试僵尸进程
int main()
{int count=5;while(count--) { printf("I am a parent process,running always! pid:%d--ppid:%d\n",getpid(),getppid());sleep(1);}pid_t id=fork();if(id==0){int count=5;while(count--){printf("I am a child process,pid:%d--ppid:%d\n",getpid(),getppid());sleep(1);}printf("-------I am a child process,running done!-------\n");}else{int count=10;while(count--){printf("I am a parent process,running always! pid:%d--ppid:%d\n",getpid(),getppid());sleep(1);}}return 0;
}
僵尸进程危害
a.
进程的退出状态必须被维持下去,因为他要告诉关心它的进程(父进程),你交给我的任务,我办的怎么样了。可父进程如果一直不读取,那子进程就一直处于Z状态。
b.
维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说,Z状态一直不退出,PCB一直都要维护。
c.
那一个父进程创建了很多子进程,就是不回收,就会造成内存资源的浪费。因为数据结构对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空间!
d.
内存泄漏 ! ! !
e. 解决办法:wait()/waitpid()!!!
6. 孤儿进程
a: 父进程如果提前退出,那么子进程后退出,进入Z之后,那该如何处理呢?
b: 父进程先退出,子进程就称之为“孤儿进程”
c: 孤儿进程被1号init进程领养,当然要有init进程回收。
#include <stdio.h>
#include <unistd.h>
#include<sys/types.h>
#include<stdlib.h>
int main()
{pid_t id = fork();if (id < 0){perror("fork");return 1;}else if (id == 0){ // childprintf("I am child, pid : %d\n", getpid());sleep(10);}else{ // parentprintf("I am parent, pid: %d\n", getpid());sleep(3);exit(0);}return 0;
}
7. 进程优先级
基本概念
a: cpu资源分配的先后顺序,就是指进程的优先权(priority),根据有优先级指定进程获取某种资源(CPU)的先后顺序。
b: 优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。
c: 还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能。
d: 保证进程在被CPU调度时的顺序性,确保了操作系统能够合理分配CPU资源,优化系统性能和响应时间。
为什么要有优先级?
a: 进程访问的资源(CPU)始终是有限的,系统中进程大部分情况都是较多的。
b: 操作系统关于调度和优先级的原则:分时操作系统,基本的公平,如果进程因为长时间得不到调度就会造成饥饿问题。
关于分时系统和实时系统:http://t.csdnimg.cn/YAZ8Qhttp://t.csdnimg.cn/YAZ8Q
查看系统进程
在linux或者unix系统中,用ps –l命令则会类似输出以下几个内容:
这里有几个重要信息:
UID : 代表执行者的身份
PID : 代表这个进程的代号
PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
PRI :代表这个进程可被执行的优先级,其值越小越早被执行
NI :代表这个进程的nice值
PRI and NI
a: PRI也还是比较好理解的,即进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序, 此值越小进程的优先级别越高
b: 那NI呢?就是我们所要说的nice值了,其表示进程可被执行的优先级的修正数值
c: PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为: PRI(new)=PRI(old)+nice
d: 这样,当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行所以,调整进程优先级,在Linux下,就是调整进程nice值
e: nice其取值范围是-20至19,一共40个级别
PRI vs NI
a: 需要强调一点的是,进程的nice值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进程的优先级变化。
b: 可以理解nice值是进程优先级的修正修正数据
8. 进程其他相关概念
a. 竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级。
b. 独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰。
c. 并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行。
d. 并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发。
http://t.csdnimg.cn/zHgwnhttp://t.csdnimg.cn/zHgwnhttp://t.csdnimg.cn/Ihg19
http://t.csdnimg.cn/Ihg19
4. 命令行参数与环境变量
命令行参数
为什么要有命令函数?:
本质:命令行参数本质是交给我们程序的不同的选型,用来制定不同的程序功能。命令中会携带很多选项。
环境变量
基本概念以及使用: http://t.csdnimg.cn/O5i49
a: 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数。(系统中很多的配置在我们登录linux系统的时候,就已经被加载到了bash进程中(内存)),所以,默认我们查到的环境变量是内存级的。
b: 如:我们在编写C/C++代码 的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
c: 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性。
之前我们提到过:直接在命令行启动的进程,他的父进程是bash。所以我们在命令行运行程序的时候,bash进程默认会给子进程两张表:
1:argv[]命令行参数表(用户输入参数) 2:env[]环境变量表(从OS的配置文件来)。
环境变量具有系统级的全局属性,因为环境变量本身会被子进程继承下去!
内建命令与外部命令
5. 程序地址空间
平台: kernel 2.6.32 32位
程序的地址空间分布图:
先来看一段代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include<sys/types.h>
int g_val = 0;
int main()
{pid_t id = fork();if (id < 0){perror("fork");return 0;}else if (id == 0){ // childprintf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);}else{ // parentprintf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);}sleep(1);return 0;
}
父子进程的地址是一样的? 变量也一样?
我们再来给代码做点小改动:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
int g_val = 0;
int main()
{pid_t id = fork();if (id < 0){perror("fork");return 0;}else if (id == 0){ // child,子进程肯定先跑完,也就是子进程先修改,完成之后,父进程再读取g_val = 100;printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);}else{ // parentsleep(3);printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);}sleep(1);return 0;
}
我们发现,父子进程,输出地址是一致的,但是变量内容不一样!
1: 变量内容不一样,所以父子进程输出的变量绝对不是同一个变量!
2:但地址值是一样的,说明,该地址绝对不是物理地址!
3:在Linux地址下,这种地址叫做虚拟地址!
4:我们在用C/C++语言所看到的地址,全部都是虚拟地址!物理地址,用户一概看不到,由OS统一管理!
OS必须负责将 虚拟地址 转化成 物理地址 。
6. 进程地址空间
分页&虚拟地址空间
父子进程是具有独立性的。
进程 = PCB(task_struct) + 程序的代码和数据 。 子进程会把父进程的很多内核数据结构全拷贝一份,地址空间的本质就是内核中的一个结构体对象。
为什么要有地址空间?
a: 将无序变有序,让进程以统一的视角看待物理内存以及自己运行的各个区域!
b: 进程管理块和内存管理模块进行解耦!
c: 拦截非法请求,对物理内存做保护
相关文章:

Linux:进程概念详解
1. 冯诺依曼体系结构 截至目前,我们所认识的计算机,都是有一个个的硬件组件组成 。 【注意】: a. 这里的存储器指的是内存 b. 不考虑缓存情况,这里的CPU能且只能对内存进行读写,不能访问外设(输入或输出设备) c.外…...

cms框架cookice注入漏洞
目录 一、环境 二、开始分析 2.1代码审计(未授权访问) 一、环境 环境私聊获取 二、开始分析 2.1代码审计(未授权访问) 我们可以看到构造函数ip是通过X_FORWARDED_FOR来获取的,而这个刚好可以伪造,那我…...
RabbitMQ高级特性 - 非持久化 / 持久化(交换机、队列、消息)
文章目录 RabbitMQ 持久化机制概述实现非持久化(交换机、队列、消息)实现持久化(交换机、队列、消息)RabbitMQ 持久化机制 概述 前面讲到了 生产者消息确认机制 和 消费者消息确认机制,保证了消息传输的可靠性,但是这还不够,试想如果 Broker 突然崩溃,那么所有的 交换…...

OpenGL ES->工作机制
渲染流程 渲染目的:输入3D立体坐标,输出绘制后的2D平面像素工作流程:顶点着色器->图元装配->几何着色器->光栅化->片段着色器->测试与混合,整个工作流程被封装在GPU内部,无法改变。运行在CPU的代码调用…...

ue4.27 C++ 解析内容为json的字符串
json字符串为 R"({"x": -1870.0, "y": -11400.0})",里面内容是个json对象。 const FString& Message R"({"x": -1870.0, "y": -11400.0})"; TSharedRef<TJsonReader<>> Reader TJs…...

图论③ | Java | 孤岛的总面积、沉没孤岛、水流问题 、建造最大岛屿
101. 孤岛的总面积 卡玛 101. 孤岛的总面积 https://kamacoder.com/problempage.php?pid1173 孤岛是那些位于矩阵内部、所有单元格都不接触边缘的岛屿。 本题要求找到不靠边的陆地面积,那么我们只要从周边找到陆地然后 通过 dfs或者bfs 将周边靠陆地且相邻的陆地都…...

基于VEH的无痕HOOK
这里的无痕HOOK指的是不破坏程序机器码,这样就可以绕过CRC或MD5的校验。 VEH利用了Windows的调试机制和异常处理,人为抛出异常,从异常的上下文中获取寄存器信息。 DLL入口 // dllmain.cpp : 定义 DLL 应用程序的入口点。 #include "pch.h" #include "CHoo…...

芯片内部如何实现过欠压功能?
大家好,这里是大话硬件。 在前面通过推送《芯片内部如何实现VREF参考稳压源?》实现了芯片内部VREF功能,今天分享一下芯片内部是如何实现过欠压保护。 UC3842芯片系列的数据手册如下: 从上面的描述可知,芯片在工作时,需要电压达到16V,但是电压跌落到10V后,芯片就不能工…...

Basic‘ attribute type should not be a container解决方法
在使用Spring Data JPA的时候,实体类中定义一个用List修饰的成员ip,IDEA会提示Basic‘ attribute type should not be a container错误,导致编译不通过。 查阅一些博客和文档说是Spring Data JPA这个框架会把实体类的属性当做是MySQL数据库中…...
Linkis-RPC的设计思想
我的技术网站 java-broke.site,有大厂完整面经,工作技术,架构师成长之路,等经验分享 Linkis-RPC的设计目标是提供一种灵活、可扩展的微服务间通信机制,支持以下功能: 异步请求与响应:支持请求方…...

31 - memmove()函数
文章目录 1 函数原型2 参数3 返回值4 示例 1 函数原型 memmove():移动内存块,函数原型如下: void * memmove ( void * destination, const void * source, size_t num );cstring库描述如下: Move block of memory 1. Copies th…...

【深度学习】创建和训练Transformer神经网络模型,将葡萄牙语翻译成英语
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言1. 安装2. 数据处理2.1 下载数据集2.2 设置标记器2.3 使用tf.data设置数据管道 3. 测试数据集4. 定义组件4.1 嵌入和位置编码层4.2 添加并规范化4.3 基础注意力…...
[Qt][多元素控件]详细讲解
目录 0.前言1.List Widget2.Table Widget3.Tree Widget 0.前言 Qt中提供的多元素控件有: 列表: QListWidgetQListView 表格: QTableWidgetQTableView 树形: QTreeWidgetQTreeView Widget和View之间的区别,以QTableWi…...
/var/log/里面的文件具体是什么?linux的登录文件
1,什么是登录文件? linux系统官方对登录文件的定义解释我就不说了,我个人理解登录文件其实就是记录系统活动信息的几个文件,登录文件其实就是系统的日志文件。 比如linux系统默认是不会安装nginx的,nginx的日志为/var…...

JVM知识总结(双亲委派机制)
文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 双亲委派机制 双亲委派类加载过程 当App尝试加载一个类时&#x…...
YOLOv2:更快更准的目标检测
目录 前言 2.1 简介 2.2 网络结构 2.3 改进方法 2.4 性能表现 前言 自从 You Only Look Once (YOLO) 系列算法问世以来,就以其独特的设计和高效的性能在目标检测领域占据了重要地位。YOLOv1 开创了单阶段检测的新纪元,通过将整个检测过程简化为一个端到端…...
硬件工程师笔面试真题汇总
目录 1、电阻 1)上拉电阻的作用 2)PTC热敏电阻作为电源电路保险丝的工作原理 2、电容 1)电容的特性 2) 电容的特性曲线 3) 1uf的电容通常来滤除什么频率的信号 3、电感 4、二极管 1)二极管特性 2)二极管伏安…...
【vue+marked】marked
一、使用marked 第一步:下载marked和代码块高亮highlight.js npm i markednpm i highlight.jsnpm i markdown-loadernpm i github-markdown-css 第二步:注册并使用 main.js import hljs from "highlight.js"; import "github-markdow…...

无人机之热成像篇
一、定义 无人机热成像技术是指将热成像相机安装在无人机云台上,通过无人机的高空飞行能力和云台的稳定性,结合红外热成像技术对目标区域进行非接触式的温度测量和图像采集。该技术利用物体发出的红外辐射来生成图像,通过测量物体表面温度分布…...

浅谈C/C++指针和引用在Linux和Windows不同环境下的编码风格
目录 0. 前言 1. 代码块、函数体上的 { } 的规范 2. 指针和引用中的 * 和 & 符号的位置 1. Linux 环境下编码风格(gcc) 2. Windows 环境下编码风格(Visual Studio) 3. 简单总结 0. 前言 C/C因为高度的自由性,并没有对一些常见的编码风格进行限制&#…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...

佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...

day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...
嵌入式常见 CPU 架构
架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集,单周期执行;低功耗、CIP 独立外设;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel(原始…...