7.Linux进程概念|冯诺依曼|操作系统|进程|进程状态|进程优先级|环境变量|程序地址空间|

【Linux】进程详解一:进程概念 【Linux】进程详解(一) 文章目录【Linux】进程详解(一)操作系统如何进行有效管理?初识进程和PCB1.基本概念2.描述进程-进程控制块(PCB)3.1 task_struct3.组织进程4.查看进程5.创建进程-fork()6.进程状态详解6.1 查看进程的状态6.2 不同的进程状态6.3 孤儿进程6.4 僵尸进程6.5 进程状态的转化 前言 在上一讲 认识冯诺依曼体系&&初识LinuxOS 中已经学到了计算机的整体的体系结构和操作系统在计算机中起到的重要作用,今天我们就来学习一下 阅读详情

冯诺依曼体系结构

我们常见的计算机,如笔记本。我们不常见的计算机,如服务器,大部分都遵守冯诺依曼体系
![[Pasted image 20260209044835.png]]

截至目前,我们所认识的计算机,都是有一个个的硬件组件组成

  • 输入单元:包括键盘, 鼠标,扫描仪, 写板等
  • 中央处理器(CPU):含有运算器和控制器等
  • 输出单元:显示器,打印机等
    关于冯诺依曼,必须强调几点:
  • 这里的存储器指的是内存
  • 不考虑缓存情况,这里的CPU能且只能对内存进行读写,不能访问外设(输入或输出设备)
  • 外设(输入或输出设备)要输入或者输出数据,也只能写入内存或者从内存中读取。
  • 一句话,所有设备都只能直接和内存打交道。

操作系统

概念

任何计算机系统都包含一个基本的程序集合,称为操作系统(OS)。笼统的理解,操作系统包括:

  • 内核(进程管理,内存管理,文件管理,驱动管理)
  • 其他程序(例如函数库, shell程序等等)
设计OS的目的
  • 与硬件交互,管理所有的软硬件资源
  • 为用户程序(应用程序)提供一个良好的执行环境
定位
  • 在整个计算机软硬件架构中,操作系统的定位是: 一款纯正的“搞管理”的软件
如何理解 “管理”
  • 管理的例子
  • 描述被管理对象
  • 组织被管理对象
    ![[Pasted image 20260209045324.png]]
总结

计算机管理硬件

  1. 描述起来,用struct结构体
  2. 组织起来,用链表或其他高效的数据结构
系统调用和库函数概念
  • 在开发角度,操作系统对外会表现为一个整体,但是会暴露自己的部分接口,供上层开发使用,这部分由操作系统提供的接口,叫做系统调用。
  • 系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以,有心的开发者可以对部分系统调用进行适度封装,从而形成库,有了库,就很有利于更上层用户或者开发者进行二次开发。

进程

基本概念
  • 课本概念:程序的一个执行实例,正在执行的程序等
  • 内核观点:担当分配系统资源(CPU时间,内存)的实体。
描述进程-PCB
  • 进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。
  • 课本上称之为PCB(process control block), Linux操作系统下的PCB是: task_struct
task_struct-PCB的一种
  • 在Linux中描述进程的结构体叫做task_struct。
  • task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息。
task_ struct内容分类
  • 标示符: 描述本进程的唯一标示符,用来区别其他进程。
  • 状态: 任务状态,退出代码,退出信号等。
  • 优先级: 相对于其他进程的优先级。
  • 程序计数器: 程序中即将被执行的下一条指令的地址。
  • 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
  • 上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。
  • I/ O状态信息: 包括显示的I/O请求,分配给进程的I/ O设备和被进程使用的文件列表。
  • 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
  • 其他信息
组织进程

可以在内核源代码里找到它。所有运行在系统里的进程都以task_struct链表的形式存在内核里。

查看进程

进程的信息可以通过 /proc 系统文件夹查看

  • 如:要获取PID为1的进程信息,你需要查看 /proc/1 这个文件夹
    ![[Pasted image 20260209165745.png]]
    ![[Pasted image 20260209191337.png]]

![[Pasted image 20260209191502.png]]
![[Pasted image 20260209191542.png]]

删除掉文件,进程还在运行,因为程序从磁盘拷贝到内存
![[Pasted image 20260209191745.png]]

  • 大多数进程信息同样可以使用top和ps这些用户级工具来获取
#include <stdio.h>  
#include <sys/types.h>  
#include <unistd.h>  
int main()  
{  
	while(1){  
		sleep(1);  
	}  
	return 0;  
}

![[Pasted image 20260209151356.png]]

  • ps axj 查看进程
  • PID,进程的唯一标识符
    ![[Pasted image 20260209153440.png]]

反向过滤掉grep
![[Pasted image 20260209153627.png]]

通过循环查找
![[Pasted image 20260209153849.png]]

通过系统调用获取进程标示符
  • 进程id(PID)
  • 父进程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;  
}

![[Pasted image 20260209163158.png]]
![[Pasted image 20260209163322.png]]
![[Pasted image 20260209163913.png]]
![[Pasted image 20260209164037.png]]

命令行当中启动的所有的程序转化的进程都是bash的子进程
![[Pasted image 20260209164315.png]]

通过系统调用创建进程-fork初识
  • 运行 man fork 认识fork
  • fork有两个返回值
  • 父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝)
#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;  
}

![[Pasted image 20260209195056.png]]
![[Pasted image 20260209195345.png]]

打印返回值
![[Pasted image 20260209201458.png]]
![[Pasted image 20260209201520.png]]

把子进程的pid返回给父进程,把0返回给子进程

  • fork 之后通常要用 if 进行分流
#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;  
}

![[Pasted image 20260209205521.png]]
![[Pasted image 20260209210454.png]]

干掉父进程,不影响子进程
![[Pasted image 20260210074245.png]]

一次创建多进程
![[Pasted image 20260210084630.png]]
![[Pasted image 20260210085628.png]]
![[Pasted image 20260210085800.png]]

进程状态

Linux内核源代码
  • 为了弄明白正在运行的进程是什么意思,我们需要知道进程的不同状态。一个进程可以有几个状态(在Linux内核里,进程有时候也叫做任务)。下面的状态在kernel源代码里定义
/*  
* 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 信号让进程继续运行。

暂停进程
![[Pasted image 20260210142743.png]]

  • X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态
进程状态查看
ps aux / ps axj 命令

![[Pasted image 20260209060200.png]]

Z(zombie)-僵尸进程
  • 僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程(使用wait()系统调用)
  • 没有读取到子进程退出的返回代码时就会产生僵死(尸)进程
  • 僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。
  • 所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态
    来一个创建维持30秒的僵死进程例子:
#include <stdio.h>  
#include <stdlib.h>  
int main()  
{  
	pid_t id = fork();  
	if(id < 0){  
		perror("fork");  
		return 1;
	}  
	else if(id > 0){ //parent  
		printf("parent[%d] is sleeping...\n", getpid());  
		sleep(30);  
	}else{  
		printf("child[%d] is begin Z...\n", getpid());  
		sleep(5);  
		exit(EXIT_SUCCESS);  
	}  
	return 0;  
}

![[Pasted image 20260210151311.png]]
![[Pasted image 20260210151604.png]]

Ptrace 详解 - tangr206 - 博客园

僵尸进程危害
  • 进程的退出状态必须被维持下去,因为他要告诉关心它的进程(父进程),你交给我的任务,我办的怎么样了。可父进程如果一直不读取,那子进程就一直处于Z状态?是的!
  • 维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说, Z状态一直不退出, PCB一直都要维护?是的!
  • 那一个父进程创建了很多子进程,就是不回收,是不是就会造成内存资源的浪费?是的!因为数据结构对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空间!
  • 内存泄漏?是的!
孤儿进程
  • 父进程如果提前退出,那么子进程后退出,进入Z之后,那该如何处理呢?
  • 父进程先退出,子进程就称之为“孤儿进程”
  • 孤儿进程被1号init进程领养,当然要有init进程回收喽。
#include <stdio.h>  
#include <unistd.h>  
#include <stdlib.h>  
int main()  
{  
	pid_t id = fork();  
	if(id < 0){  
		perror("fork");  
		return 1;  
	}  
	else if(id == 0){//child  
		printf("I am child, pid : %d\n", getpid());  
		sleep(10);  
	}else{//parent  
		printf("I am parent, pid: %d\n", getpid());  
		sleep(3);  
		exit(0);  
	}  
	return 0;  
}

![[Pasted image 20260210153256.png]]
![[Pasted image 20260210153317.png]]

进程优先级

基本概念
  • cpu资源分配的先后顺序,就是指进程的优先权(priority)。
  • 优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。
  • 还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能。
查看系统进程

在linux或者unix系统中,用ps –l命令则会类似输出以下几个内容:
![[Pasted image 20260209061635.png]]

我们很容易注意到其中的几个重要信息,有下:

  • UID : 代表执行者的身份
  • PID : 代表这个进程的代号
  • PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
  • PRI :代表这个进程可被执行的优先级,其值越小越早被执行
  • NI :代表这个进程的nice值
PRI and NI
  • PRI也还是比较好理解的,即进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序,此值越小进程的优先级别越高
  • 那NI呢?就是我们所要说的nice值了,其表示进程可被执行的优先级的修正数值
  • PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为: PRI(new)=PRI(old)+nice
  • 这样,当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行
  • 所以,调整进程优先级,在Linux下,就是调整进程nice值
  • nice其取值范围是-20至19,一共40个级别。
PRI vs NI
  • 需要强调一点的是,进程的nice值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进程的优先级变化。
  • 可以理解nice值是进程优先级的修正修正数据
查看进程优先级的命令
用top命令更改已存在进程的nice:
  • top
  • 进入top后按“r”–>输入进程PID–>输入nice值
    ![[Pasted image 20260210160020.png]]
    ![[Pasted image 20260210160240.png]]
其他概念
  • 竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级
  • 独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰
  • 并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行
  • 并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发

进程调度
![[Pasted image 20260211090726.png]]

环境变量

命令行参数

![[Pasted image 20260211093627.png]]
![[Pasted image 20260211095327.png]]

把命令行当中的参数,转换成一个一个字串
$:bash给我们输出的命令行字符串,后面的内容是输入字符串
相当于输入“./myprocess -a -b -c -d -e”
bash把字符串按空格转换成小字符串,维护一个char*类型的数组argv,把第一个子串放到数组0下标里,数组保证最后一个下标以NULL结尾;还会有一个计数器6
会把6和指针数组传给main函数
![[Pasted image 20260211103133.png]]

![[Pasted image 20260211103537.png]]
![[Pasted image 20260211103602.png]]

可以通过不同的选项,让同一个程序执行它内部不同的功能
选项的本质就是命令行参数
命令行计算器
![[Pasted image 20260211105247.png]]

基本概念
  • 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
  • 如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
  • 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性
常见环境变量
  • PATH : 指定命令的搜索路径
  • HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
  • SHELL : 当前Shell,它的值通常是/bin/bash。
查看环境变量方法

echo $NAME //NAME:你的环境变量名称
![[Pasted image 20260211111931.png]]

测试PATH
  1. 创建hello.c文件
#include <stdio.h>  
int main()  
{  
	printf("hello world!\n");  
	
	return 0;  
}
  1. 对比./hello执行和之间hello执行

  2. 为什么有些指令可以直接执行,不需要带路径,而我们的二进制程序需要带路径才能执行?

  3. 将我们的程序所在路径加入环境变量PATH当中, export PATH=$PATH:hello程序所在路径
    ![[Pasted image 20260211112149.png]]

  4. 对比测试

  5. 还有什么方法可以不用带路径,直接就可以运行呢?
    ![[Pasted image 20260211112605.png]]

测试HOME
  1. 用root和普通用户,分别执行 echo $HOME ,对比差异
    . 执行 cd ~; pwd ,对应 ~ 和 HOME 的关系
    ![[Pasted image 20260211114031.png]]
    ![[Pasted image 20260211114152.png]]
和环境变量相关的命令
  1. echo: 显示某个环境变量值

  2. export: 设置一个新的环境变量
    ![[Pasted image 20260211120554.png]]

  3. env: 显示所有环境变量
    ![[Pasted image 20260211115939.png]]

  4. unset: 清除环境变量

  5. set: 显示本地定义的shell变量和环境变量
    ![[Pasted image 20260211132843.png]]
    ![[Pasted image 20260211132907.png]]

bash帮忙维护两张表,一张命令行参数表,一张环境变量表,给main函数传参,一方面根据选项执行不同的功能,一方面根据环境变量获取不同的环境变量属性
![[Pasted image 20260211134800.png]]
![[Pasted image 20260211134958.png]]
![[Pasted image 20260211135438.png]]

![[Pasted image 20260211135759.png]]
![[Pasted image 20260211135858.png]]
![[Pasted image 20260211135937.png]]

环境变量具有全局属性,环境变量会被所有的子进程包括孙子进程进行继承

![[Pasted image 20260211140929.png]]
![[Pasted image 20260211141057.png]]

![[Pasted image 20260211141451.png]]

可以通过环境变量实现身份识别

环境变量的组织方式

![[Pasted image 20260209064027.png]]

每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串

通过代码如何获取环境变量
  • 命令行第三个参数
#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;  
}
  • 通过第三方变量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;  
}

![[Pasted image 20260211175546.png]]
![[Pasted image 20260211175253.png]]
![[Pasted image 20260211175738.png]]

libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时 要用extern声明。

通过系统调用获取或设置环境变量

putenv

  • getenv
#include <stdio.h>  
#include <stdlib.h>  
int main()  
{  
	printf("%s\n", getenv("PATH"));  
	return 0;  
}

![[Pasted image 20260211180113.png]]

常用getenv和putenv函数来访问特定的环境变量。

添加hello本地变量
![[Pasted image 20260211181600.png]]
![[Pasted image 20260211181723.png]]
![[Pasted image 20260211181753.png]]
![[Pasted image 20260211181431.png]]

./myenv运行的时候,就是bash的子进程
![[Pasted image 20260211181825.png]]

  • 修改配置文件
    ![[Pasted image 20260212000337.png]]
    ![[Pasted image 20260212000752.png]]

本地变量不是环境变量,不能被子进程继承下去,只能在bash内部有效
环境变量是在bash的上下文里的,bash就是命令行解释器,所有的环境变量都是从文件里读来的,在内存里形成一段缓冲区,形成对应的环境变量表
![[Pasted image 20260212091655.png]]

.bashrc,脚本,导入环境变量
![[Pasted image 20260212101131.png]]

导入环境变量
![[Pasted image 20260212103749.png]]

![[Pasted image 20260212164948.png]]
![[Pasted image 20260212165008.png]]

![[Pasted image 20260212171026.png]]
![[Pasted image 20260212171746.png]]

环境变量通常是具有全局属性的
  • 环境变量通常具有全局属性,可以被子进程继承下去
#include <stdio.h>  
#include <stdlib.h>  
int main()  
{  
	char * env = getenv("MYENV");  
	if(env){  
		printf("%s\n", env);  
	}  
	return 0;  
}

直接查看,发现没有结果,说明该环境变量根本不存在

  • 导出环境变量 export MYENV="hello world"
  • 再次运行程序,发现结果有了!说明:环境变量是可以被子进程继承下去的

程序地址空间

研究背景
  • kernel 2.6.32
  • 32位平台
程序地址空间回顾

空间布局图
![[Pasted image 20260209065421.png]]

![[Pasted image 20260212174208.png]]
![[Pasted image 20260212174343.png]]

![[Pasted image 20260212175836.png]]
![[Pasted image 20260212181909.png]]

![[Pasted image 20260212191029.png]]
![[Pasted image 20260212193206.png]]

![[Pasted image 20260212193713.png]]
![[Pasted image 20260212193735.png]]

无论是表还是表指向的项目,都在栈上部

![[Pasted image 20260212195027.png]]
![[Pasted image 20260212195044.png]]

![[Pasted image 20260212195107.png]]
![[Pasted image 20260212195127.png]]

静态变量是全局变量

![[Pasted image 20260213084024.png]]
![[Pasted image 20260213084056.png]]

![[Pasted image 20260213084427.png]]
![[Pasted image 20260213084452.png]]

我们发现,父子进程,输出地址是一致的,但是变量内容不一样!能得出如下结论:

  • 变量内容不一样,所以父子进程输出的变量绝对不是同一个变量
  • 但地址值是一样的,说明,该地址绝对不是物理地址!
  • 在Linux地址下,这种地址叫做 虚拟地址
  • 我们在用C/C++语言所看到的地址,全部都是虚拟地址!物理地址,用户一概看不到,由OS统一管理
    OS必须负责将 虚拟地址 转化成 物理地址 。
    这个地址不是物理地址,是虚拟地址/线性地址
    最开始的程序地址空间不是物理空间,叫做进程地址空间
进程地址空间

所以之前说‘程序的地址空间’是不准确的,准确的应该说成 进程地址空间 ,那该如何理解呢?看图:
![[Pasted image 20260209070331.png]]

说明:

  • 上面的图就足矣说明问题,同一个变量,地址相同,其实是虚拟地址相同,内容不同其实是被映射到了不同的物理地址!
    进程地址空间,每一个进程,都会存在一个进程地址空间,32[0, 4GB]
    ![[Pasted image 20260213103627.png]]

区域划分的本质就是,区域内的各个地址,都可以使用
进程地址空间,不具备对代码和数据保存的能力,它们是在物理内存中存放的,将地址空间上的地址(虚拟/线性)转化到物理内存中,给进程提供一张映射表,页表

为什么要有地址空间+页表

  1. 将物理内存从无序变有序,让进程以统一的视角,看待内存
  2. 将进程管理与内存管理进行解耦合
  3. 地址空间+页表是保护内存安全的重要手段

Linux2.6内核进程调度队列

上图是Linux2.6内核中进程队列的数据结构,之间关系也已经给大家画出来,方便大家理解

一个CPU拥有一个runqueue
  • 如果有多个CPU就要考虑进程个数的负载均衡问题
优先级
  • 普通优先级: 100~ 139(我们都是普通的优先级,想想nice值的取值范围,可与之对应!)
  • 实时优先级: 0~ 99(不关心)
活动队列
  • 时间片还没有结束的所有进程都按照优先级放在该队列
  • nr_active: 总共有多少个运行状态的进程
  • queue[140]: 一个元素就是一个进程队列,相同优先级的进程按照FIFO规则进行排队调度,所以,数组下标就是优先级!
  • 从该结构中,选择一个最合适的进程,过程是怎么的呢?
  1. 从0下表开始遍历queue[140]
  2. 找到第一个非空队列,该队列必定为优先级最高的队列
  3. 拿到选中队列的第一个进程,开始运行,调度完成!
  4. 遍历queue[140]时间复杂度是常数!但还是太低效了!
  • bitmap[5]:一共140个优先级,一共140个进程队列,为了提高查找非空队列的效率,就可以用5*32个比特位表示队列是否为空,这样,便可以大大提高查找效率!
过期队列
  • 过期队列和活动队列结构一模一样
  • 过期队列上放置的进程,都是时间片耗尽的进程
  • 当活动队列上的进程都被处理完毕之后,对过期队列的进程进行时间片重新计算
active指针和expired指针
  • active指针永远指向活动队列
  • expired指针永远指向过期队列
  • 可是活动队列上的进程会越来越少,过期队列上的进程会越来越多,因为进程时间片到期时一直都存在的。
  • 没关系,在合适的时候,只要能够交换active指针和expired指针的内容,就相当于有具有了一批新的活动进程!
总结
  • 在系统当中查找一个最合适调度的进程的时间复杂度是一个常数,不随着进程增多而导致时间成本增加,我们称之为进程调度O(1)算法!
    Linux的进程优先级 NI 和 PR - 简书
LT9211 单路mipi转双路mipi芯片,方案成熟,提供技术支持 LT9211 单路mipi转双路mipi芯片 阅读详情

相关推荐

《AFSim 2.9中文参考手册》

本栏目将对《AFSim 2.9中文参考手册》进行持续更新,欢迎关注交流!对本文或者AFSIM相关内容感兴趣的朋友,可私心联系作者。《AFSim 2.9中文参考手册》内容概览。

henggesim的博客 1万+

【linux】进程概念详述

进程概念

qq_66314292的博客 6339

AI中台系统设计方案探讨

集成JupyterLab、低代码建模工具(如H2O.ai)、预训练模型库(Hugging Face、PaddleHub)。:通过REST/gRPC接口封装AI能力(如OCR、语音识别),支持流量控制与鉴权(如Kong、Apigee)。:服务注册发现(Consul)、熔断降级(Hystrix)、监控告警(Prometheus+Grafana)。:分布式存储(如HDFS、Ceph)与对象存储(如S3、OSS),支持海量数据高速读写。加密传输(TLS)、动态脱敏(如数据掩码)、访问控制(RBAC)。

reset2021的博客 1032

【Linux操作系统】进程概念

本文系统性地介绍了计算机系统中的核心概念与运行机制。首先阐述了冯诺依曼体系结构的基本原理及其性价比优势,说明了CPU通过内存与外设交互的必要性。然后深入解析了操作系统的核心功能与管理逻辑,包括"先描述后组织"的管理思想、进程控制块(PCB)的作用以及进程状态转换。文章详细探讨了进程调度算法、优先级机制、环境变量管理,并重点剖析了虚拟地址空间的实现原理及其保护机制。最后通过代码实例验证了程序地址空间的布局特征,揭示了虚拟地址与物理地址的映射关系。全文从硬件架构到软件管理层层递进,构建了完整

2401_82610555的博客 3551

实验室LIMS系统选型指南:从赛默飞到金现代,5大主流方案横评

本文深入分析了实验室LIMS系统选型的5大核心维度,包括架构选择、行业适配性、合规性设计、智能化程度和成本模型。通过对比赛默飞、金现代等主流厂商的优劣势,提供实战避坑策略,帮助实验室管理者做出明智决策,提升运营效率和合规水平。

plum99的博客 259

手把手教你用DLP4500和海康相机搭建双目结构光系统(附完整代码获取路径)

本文详细介绍了如何利用DLP4500投影仪和海康工业相机搭建低成本双目结构光三维测量系统。从硬件选型、软件配置到结构光编码解码实现,再到三维重建全流程,提供了完整的实战指南和优化技巧,帮助用户以不到2万元的预算实现0.05mm精度的三维扫描。

weixin_32447969的博客 316

【Linux】Linux进程的理解 --- 冯诺依曼体系、进程描述符、状态、优先级、切换…

冯诺依曼、操作系统、进程状态、进程优先级、进程切换

The porters of knowledge 5912

基于Termux的Android平台OpenClaw部署:移动端AI助理实现

本文介绍了在Android设备上通过Termux部署OpenClaw AI助理的方案。Android设备的便携性、Termux提供的完整Linux环境以及多样化的硬件配置使其成为理想的部署平台。文章详细分析了不同级别Android设备的硬件规格(从入门级到旗舰级),并提供了最低/推荐配置要求。部署步骤包括Termux安装初始化、Python环境配置以及性能优化建议。该方案充分利用Android设备的传感器和电池供电优势,为移动办公、学习等场景提供了低成本、高便携性的AI助理解决方案。

博客 3011

Linux进程概念

冯诺依曼体系结构是当代计算机的基本结构,它主要包括几个板块,输入设备,输出设备,存储器,运算器和控制器。下面是简略版的图解析:输入设备主要包含鼠标,键盘,话筒等主要进行数据的传输;存储器即内存用于将接受输入设备的数据,为数据进行排队后交给CPU处理,在CPU数据返回后再传给输出设备,因此内存是冯诺依曼体系结构最重要的部分;接着是CPU,运算器和控制器结合构成了CPU,运算器主要负责进行代码的逻辑运算和算数运算,控制器主要负责对代码进行控制;最后是输出设备,主要是显示器,喇叭等负责数据的输出。

2401_86449430的博客 1万+

利用 AI 自动生成 BDD(行为驱动开发)格式的 Gherkin 测试用例

文章摘要 当前BDD测试领域正经历AI驱动的变革浪潮。传统Gherkin用例编写面临四大痛点:语法负担重、场景发现成本高、一致性差和维护困难。2025-2026年,AI生成Gherkin的工具生态快速成熟,主要分为五类:测试管理平台内置AI(如TestRail 10.2)、Jira插件(如AssertThat BDD)、独立AI平台(如PrimeCompass)、CLI工具和研究原型。其中,TestRail实现生成-执行闭环,AssertThat采用多阶段Agent工作流提升质量,PrimeCompass则

ZXSXJ的博客 205

logisim中,如何设计一个位于十字路口的交通信号灯控制系统?

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值。

**My Coding Family** 1342

Linux之进程概念

Linux之进程概念

2302_81120572的博客 2089

【AI产品与商业航图】Flux.1 完全开源 AI 绘图模型:本地部署与 ComfyUI 实战指南

Flux.1是一个开源项目,用户可以自由使用和修改,完全免除使用费用。🖥️本地部署支持:与一些依赖云端计算的工具不同,Flux.1支持本地部署,确保用户可以离线使用并自主控制数据隐私。🔄兼容ComfyUI框架:Flux.1可以无缝集成到ComfyUI中,用户可以享受更加简便和直观的操作界面。🎨卓越的图像生成能力:Flux.1能够生成高质量、细腻的图像,支持多种风格与创作主题的切换。💾低硬件要求。

高校图书馆高级系统架构师/研究馆员,推动高校AI从概念演示到可评审、可交付、可运维:路线图与立项评审、PoC交付、评测回归与上线运维(Baseline/Eval/Ops)。 1736

Linux系统-进程概念

Linux进程概念零、前言一、冯诺依曼体系结构二、操作系统三、进程1、描述进程-PCB2、查看进程3、获取进程标示符4、创建进程-fork()5、进程状态6、僵尸进程7、孤儿进程8、进程优先级9、环境变量1)测试PATH2)测试HOME3)如何获取环境变量4)命令行变量 零、前言 本章主要讲解操作系统的一些基础概念知识,为进程的学习做铺垫 一、冯诺依曼体系结构 概念: 冯诺依曼体系结构规定了硬件上的数据流动,而大部分计算机都遵守冯诺依曼体系,如笔记本,服务器等 示图: 计算机基本硬件组成

~ 8066

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Linux-进程概念

return 0;//child,子进程肯定先跑完,也就是子进程先修改,完成之后,父进程再读取 g_val = 100;}父子进程中的g_val的地址竟然是一样的任何的编程语言里面的地址,绝对不是物理地址,而是虚拟地址(C++/C语言中的&得到的是虚拟地址不是物理地址)虚拟地址是操作系统提供的,数据和代码一定在物理内存上(冯诺依曼规定),因此需要将虚拟内存转化成物理内存(由OS自动完成)父子进程代码共享,而数据是各自私有一份的(写时拷贝)

AI_ELF的博客 5256

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

【Linux】进程概念 —— 冯诺依曼体系结构 | 操作系统 | 进程

本文主要介绍了计算机系统中的进程概念及相关知识。 首先从冯诺依曼体系结构出发,说明CPU与内存的关系,指出内存是体系结构的核心设备。 然后介绍操作系统的定位和作用:管理软硬件资源,为用户提供稳定高效的运行环境。通过"先描述,再组织"的理念进行管理。 重点讲解进程的概念:操作系统通过进程控制块(PCB)描述进程,在Linux中表现为task_struct结构体,包含进程状态、优先级、内存指针等属性。 说明进程的组织方式:用双向链表将PCB组织起来,使进程管理变为对数据结构的操作。 提供查看

浮光掠影 5106

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

【Linux】进程概念万字详解(上篇)

Linux进程概念部分详解,还有下篇

m0_60338933的博客 4537

【Linux进程概念——上】冯 • 诺依曼体系结构 | 操作系统 | 进程 | fork | 进程状态 | 优先级

从此篇开始,就开始学习 Linux 系统部分 —— 进程,在正式学习 Linux 进程之前,我们需要铺垫一些概念,如冯诺依曼体系结构、操作系统的概念及定位、进程概念,我们会先铺垫理论,再验证理论。其次对于某些需要深入的概念我们只是先了解下。本文中的 fork 只会介绍基本使用,以及解答 fork 为啥会有 2 个返回值、为啥给子进程返回 0,而父进程返回子进程的 pid;而对于用于接收 fork 返回值的 ret 是怎么做到 ret == 0 && ret > 0、写时拷贝、代码是怎么做到共享的、数据是怎么

DanceBit的博客 4786

【Linux】进程状态、进程优先级和进程切换

本篇博客基于学习完冯诺依曼体系结构与操作系统及其进程,进一步深度理解进程,学习完本篇对进程的理解会更上一层楼,想必大家已经按耐不住接收新的知识,那咱们话不多说进入今天的主题--->【Linux】进程状态、进程优先级和进程切换😳😳。⭐主体我们从以下学习【Linux】进程状态、进程优先级和进程切换🤗🤗。

AAlykk的博客 5066

[Linux][进程概念][进程优先级]详细解读

[Linux][进程概念][进程优先级]详细讲解

SnowK博客 5367

Linux | 进程相关概念(进程、进程状态、进程优先级、环境变量、进程地址空间)

将父进程的大部分属性拷贝过去(不在内的如pid、ppid),由于父子进程属于同一个程序,他们的代码是共用的,但是两个进程同时访问一个变量的时候会出现冲突问题,因此子进程会将它将要访问的数据做一份额外的拷贝,也就是子进程访问拷贝出来的数据,然后父子进程就有了属于各自的数据,对变量的操作也是独立的。​ 进程需要执行的时候,会被加入到运行队列中,并由调度器对队列进行调度,在CPU中执行运行的进程,无论是在运行中的还是在运行队列中的进程都是在R运行状态。因此每个进程都会有自己的PCB即。

TTKunn的博客 1654

【Linux】浅谈冯诺依曼和进程

它提供用户接口和资源分配,是计算机系统中最基本的系统软件,任何计算机系统都包含一个基本的程序集合,统称为。9. I / O状态信息:包含显示的 I / O 请求,分配给进程的 I / O 设备和被进程使用的文件链表。5. 优先级:用来描述进程被调度的先后的数字,数字小的优先级高,数字大的优先级低,和成绩排名有异曲同工之妙。X死亡状态:这是一个返回状态,你不会在任务列表中看到这个状态,因为这是一个瞬时状态,一下就消失了。因为进程这里大部分时间都在做IO交互,IO的时间是很慢的,所有看不到R状态。

2303_80187476的博客 2231

Linux系统(四)- 进程初识 | 环境变量 | 进程地址空间

进程 | 环境变量 | 进程地址空间

分享简单技术,记录点滴成长 1464

Linux 进程概念

进程PCB,fork,僵尸、孤儿进程,调度切换,环境变量

m0_73299878的博客 1600

冯诺依曼体系结构、操作系统、Linux进程概念、环境变量、进程地址空间

冯诺依曼体系结构、操作系统、Linux进程概念、环境变量、进程地址空间,总结一下,清晰多了。

GD_small_bit的博客 2352

【Linux升级之路】3_Linux进程概念

认识冯诺依曼系统,操作系统概念与定位,深入理解进程概念(了解PCB),学习进程状态(创建进程、僵尸进程和孤儿进程),进程优先级&进程切换(进程竞争性与独立性、并行与并发),环境变量(设置、获取环境变量、相关指令),进程地址空间(内存空间分配规律、认识地址空间)

Captain_ldx的博客 1989
上一篇: 6.Linux环境基础开发工具使用|yum|vim|gcc/g++|gdb|make/makefile|进度条|git
下一篇: 8.Linux进程控制|进程创建|进程终止|进程等待|进程程序替换|简易shell实现
ChoSeitaku
博客等级 码龄5年 3452粉丝 557原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值