科林Linux_3 进程

news2025/1/10 12:14:17

一、进程基础

操作系统基础的执行单元,调度单位

静态数据:只占用磁盘空间,不消耗其他资源

动态数据:磁盘 内存 CPU

1. 编译器将源码编译成一个可执行文件.exe/.elf

2. 运行后系统生成一个同名的进程

程序是进程的静态表现,进程是程序的动态表现

3. 进程在创建时,要分配虚拟内存(线程不分配内存)

进程是最小的分配资源单位,也是调度单位

因为每个进程创建时分配内存资源,所以被成为分配资源单位

进程没有实体,由复杂的逻辑关系构成

进程的生存环境,形态:

PCB 进程控制块,是一个300多个成员的结构体,记录了详细的进程信息

虚拟内存地址通过内存映射访问真正的物理内存地址

进程中虚拟地址不同,但是指向相同的物理地址,实现共享内存【内核空间】

不同的进程内存独立【用户空间】(以防互相影响,内核空间只有系统拥有权限,不怕被修改)

程序优化:系统占用以及系统开销(CPU 内存)

内存基本单位:Page(页) 1Page=4KB=4096Bytes

malloc(8192) ——> 一次分配两页内存

malloc(5000) ——>分配两页内存,对剩余内存空间进行限制访问

malloc(3192) ——>检查是否使用完毕,并解除限制

内存的权限:PROT_READ 只读 PROT_WRITE 只写 PROT_EXEC 执行 PROT_NONE 无权限

虚拟内存:32位系统,三级间接寻页:1024*1024*1024=GB

63位系统,四级间接寻页,1024*1024*1024*1024=TB


 

二、进程状态以及状态转换

进程的五种常态

就绪态Ready:进程已准备除处理器外所需资源,等待cpu资源

运行态Running:占用cpu,正在执行指令

阻塞态Blocked:由于进程等待某种条件(如I/O操作或进程同步)被暂停(释放cpu),在条件满足之前无法继续执行。

挂起态Suspend:由于用户和系统的需要被暂停(释放cpu),把进程从内存转到外存

终止态Terminated:进程退出,释放进程内存资源

阻塞态和挂起态的区别?

1. 阻塞态可以被中断,在等待的资源得到满足后,进入就绪状态;挂起态无法被中断,只有将其挂起的对象唤醒后,才可以让其继续

2. 阻塞态释放了cpu,但是阻塞的进程还在内存中;挂起的进程通过swp交换到外存中(磁盘空间)

3. 阻塞态发生在进程等待资源时,挂起是由于用户和系统需要

任意状态都可以切换为终止态

Linux独有的状态

僵尸态Zombie:子进程退出结束,但是PCB残留,导致内存泄漏,叫做僵尸进程

孤儿态Orphan:父进程先挂掉,子进程会被1号进程领养,我们可以理解为操作系统,或者说父进程先结束,子进程必须被操作系统领养,因为无主进程,一直僵尸浪费资源,我们将这种进程称之为孤儿进程。 还会将自己变成后台进程。

分时复用原则(时间片)

多进程共享使用CPU,每个进程按时间片(10us)使用,而后快速切换,既可以让多个进程共享使用,以提高cpu使用率

单任务操作系统(软盘) ——> 多任务操作系统(充分共享使用硬件)

大多数系统的程序都是并发执行的(快速交替执行)

保存与恢复处理器现场

CPU原件:控制器、寄存器(Eax,Ebx,Edx,Eflag....)、编码器、译码器、运算器

寄存器:

内存:快速缓存数据及计算过程

每个进程都有自己独立的PCB,每个PCB都有一个内核栈指针kernel_ptr,指向自己的内核栈

多任务基准:分时+保存与恢复
 

什么是线程?什么是进程?

进程或者线程就是寄存器(CPU的访问权)和栈(内核栈)

进程、线程、纤程:调度单位

协程、管程:管理单元

超线程:硬件,模拟多核

二、进程源语

2.1 进程源语函数

系统支持进程开发提供的一系列API函数接口

pid_t pid;进程id类型

pid_t pid=getpid(void);//调用获取进程pid

2.1.1 fork() 创建子进程

pid_t pid=fork(); //创建子进程,执行一次创建一个进程

子进程与父进程pid连续,父进程最小

父进程调用fork,系统创建子进程,子进程从fork之后执行

关于子进程继承的问题?

 1. 拷贝继承

2. 区分父子进程代码段,实现父子执行不同的代码任务

使用fork的返回值pid进行父子进程的区分

子进程不允许踏出工作区

1. 永久阻塞 2. 进程退出

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

//parent start
int main(){
	pid_t pid;
	pid=fork();  //创建子进程
	if(pid>0){
		printf("parent pid %d, Running...\n",getpid());
	}
	else if(pid==0){
		//child start
		printf("child pid %d, Running...\n",getpid());
		while(1)
			sleep(1);
		//child end
	}
	else if(pid==-1){
		perror("fork call failed");
		exit(0);
	}
	printf("self id %d\n",getpid());
	while(1)
		sleep(1);

	return 0;
}
//parent end

windows的printf自带刷新缓冲区

linux下\n刷新缓冲区

3. 创建多进程

循环创建多进程

int i;
for(int i=0;i<3;i++){
    pid=fork();
    if(pid==0)
        break;
}

4. 子进程执行fork,并且得到返回值0

两个进程执行同一个fork()

栈帧

不同的函数有各自的函数栈帧地址,其他位置无法访问函数内部资源

父子进程可以共享同一个函数的栈帧地址,实现调用同一个函数,执行一部分

gdb可以实现栈帧的跳转

第一版 fork,拷贝继承版本

如果子进程不需要拷贝父进程数据,而是自行获取用户空间,那么父进程的拷贝流程和开销变成无意义的系统开销

第二版 vfork,无拷贝过程,但是不能直接使用

通过vfork创建的子进程没有用户空间,需要用户自行生成用户层,vfork必须结合execl函数使用

第三版 fork,读共享写复制

读时共享,虚拟地址不同,物理地址相同

父子进程写都会导致子进程复制共享内存数据

例题:

2*9+1=19个子进程

2*10-1=19

2.1.2 execl() 进程重载

系统名都是程序,执行命令时创建进程,完成特定功能

重载只替换进程工作数据,与PCB进程信息无关

    execl("程序路径",argv[0]/*文件名|命令*/,argv[1]/*参数*/,NULL/*哨兵,结束*/);
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

int main(){
	pid_t pid;
	pid=fork();
	if(pid>0){
		printf("parent pid %d\n",getpid());
		while(1)
			sleep(1);
	}
	else if(pid==0){
		printf("child pid %d\n",getpid());
		printf("child execl...\n");
		execl("/usr/bin/firefox","firefox","www.bilibili.com",NULL);
		printf("execl failed\n");
		exit(0);
	}
	else if(pid<0){
		printf("fork failed\n");
		exit(0);
	}
	return 0;
}

使用execl

1. vfork创建子进程无法直接使用,必须重载才可以使用

2. 重载方便程序的功能扩展,很多现有的命令在进程中可以直接使用

3. 动态迭代

在程序不下线的情况下,动态更新功能

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

int main(){
	pid_t pid;
	printf("MyWeb Vesion 1.o Running...\n");
	while(1){
		pid=fork();
		if(pid==0)
			break;
		sleep(5);
	}
	if(pid==0)
		execl("./MOD/mod1","mod1",NULL);
	return 0;
}

此时只需要修改mod1.c文件内容并重新编译,就可以在线修改主程序的功能

2.1.3 wait() waitpid() 回收函数

僵尸态Zombie:子进程退出结束,但是PCB残留,导致内存泄漏,叫做僵尸进程

_EXIT(0) 结束进程时,完全释放了用户空间,释放了部分内核空间,只有PCB残留——内存泄漏

危害:1. 内存泄漏 2. 僵尸进程残留PCB无法给新进程使用,影响进程创建数量

系统为何要保留PCB?

僵尸进程需要父进程进行手动回收、检验子进程是否正常退出

关于ps -aux进程状态stat的中Ss、S<l、Ssl、SLl、SNl、R、R+的解释_ps aux 进程 tl sl-CSDN博客

int stat;
pid_t zpid=wait(NULL);    //表示只回收pcb不进行回收的验证操作,返回值为僵尸进程pid
pid_t zpid=wait(&stat);    //返回子进程状态

wait() 失败原因:没有子进程立即失败
wait() 是阻塞函数,阻塞回收,如果子进程未结束,无需回收,wait阻塞等待

 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

int main(){
	pid_t pid;
	pid_t zpid;
	pid=fork();
	if(pid>0){
		zpid=wait(NULL);
		printf("parent pid %d, child pid %d, zpid %d\n",getpid(),pid,zpid); 
		while(1)
			sleep(1);
	}
	else if(pid==0){
		printf("child alive 10s\n");
		sleep(10);
		exit(0);
	}
	else {
		perror("fork failed");
		exit(0);
	}
	return 0;
}

只有父进程可以回收子进程,其他进程无法代替 

init 1号进程没有父进程,称作根进程

子进程先于父进程死亡,必然会成为僵尸;父进程先于子进程死亡,子进程必然会成为孤儿

waitpid(pid_t pid,int* state,WNOHANG/*非阻塞关键字*/);    
//返回值:>0 成功返回| -1 失败| =0 非阻塞返回
    pid==-1 回收任意子进程
    pid>0 回收指定子进程(进程号)
    pid==0 同组回收
    pid<-1 跨组回收(-进程组号)

waipid() 支持非阻塞回收,相比wait() 更加灵活。在等待回收时,父进程可以执行自己的任务和代码。

Linux之进程的基本概念(进程,进程组,会话关系)_linux 会话id-CSDN博客

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

int main(){
	pid_t pid;
	pid_t zpid;
	pid=fork();
	if(pid>0){
		while((zpid=waitpid(-1,NULL,WNOHANG))!=-1){
			if(zpid>0)
				printf("parent pid %d, child pid %d, zpid %d\n",getpid(),pid,zpid); 
			else if(zpid==0){
				printf("parent exec jobs\n");
				sleep(1);
			}
		}
		while(1)
			sleep(1);
	}
	else if(pid==0){
		printf("child alive 10s\n");
		sleep(10);
		exit(0);
	}
	else {
		perror("fork failed");
		exit(0);
	}
	return 0;
}

2.2 多进程拷贝

单进程的CPU使用资源受限,可以采用多进程模型,获取更多的时间片,加快任务完成速度,提高效率

两种常见的多进程:多进程任务较为复杂;多进程任务单一

串行:逐次完成任务

并行:多核CPU且每一个工作进程都能加载到对应的处理核心上【由CPU决定,不可控】

并发:单个处理器,逻辑上同步执行【有并行的概率】多进程并发、多线程并发

程序的执行效率由cpu的占用及使用频率决定,占用越多效率越高

单进程模型因阻塞或其他原因放弃本轮cpu使用,但是多进程或者多进程模型,根据就近原则,放弃的进程可以交替给相邻的进程,让任务继续

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1619118.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

用 LM Studio 1 分钟搭建可在本地运行大型语言模型平台替代 ChatGPT

&#x1f4cc; 简介 LM Studio是一个允许用户在本地离线运行大型语言模型&#xff08;LLMs&#xff09;的平台&#xff0c;它提供了一种便捷的方式来使用和测试这些先进的机器学习模型&#xff0c;而无需依赖于互联网连接。以下是LM Studio的一些关键特性&#xff1a; 脱机&am…

JavaScript:js基础2

BOM Browser Object Model浏览器对象模型 允许JavaScript与浏览器进行对话 Js将浏览器的各个组成部分封装为对象 可以通过操作BOM对象来实现操作浏览器中的部分 location.href "" //操作浏览器地址栏中的地址BOM中包含了以下对象 window:浏览器窗口对象 Navi…

Leetcode算法训练日记 | day34

专题九 贪心算法 一、K次取反后最大化的数组和 1.题目 Leetcode&#xff1a;第 1005 题 给你一个整数数组 nums 和一个整数 k &#xff0c;按以下方法修改该数组&#xff1a; 选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。 重复这个过程恰好 k 次。可以多次选择同一个…

python爬虫 - 爬取html中的script数据(36kr.com新闻信息)

文章目录 1. 分析页面内容数据格式2. 使用re.findall方法&#xff0c;爬取新闻3. 使用re.search 方法&#xff0c;爬取新闻 1. 分析页面内容数据格式 打开 https://36kr.com/ 按F12&#xff08;或 在网页上右键 --> 检查&#xff08;Inspect&#xff09;&#xff09; 找…

HarmonyOS开发案例:【相机开发】

基本概念 相机是OpenHarmony多媒体进程提供的服务之一&#xff0c;提供了相机的录像、预览、拍照功能&#xff0c;支持多用户并发取流。 在进行应用的开发前&#xff0c;开发者应了解以下基本概念&#xff1a; 视频帧 视频流指的是将一系列图片数据按照固定时间间隔排列形成的…

开发日志(20240422):一次以为是跨域但并不是跨域的问题排查记录

1. 日志 在前后端联调的时候&#xff0c;遇到了报错&#xff0c;如下图所示&#xff08;现在再看感觉非常简单了&#xff09;&#xff0c;发现前一个请求通过了&#xff0c;但是第二个请求报错&#xff0c;然后看到 strict-origin-when-cross-origin 条件反射的认为是跨域配置…

iOS - 多线程-GCD-队列组

文章目录 iOS - 多线程-GCD-队列组1. 队列组1.1 基本使用步骤 iOS - 多线程-GCD-队列组 开发过程中&#xff0c;有时候想实现这样的效果 多个任务并发执行所有任务执行完成后&#xff0c;进行下一步处理&#xff08;比如回到主线程刷新UI&#xff09; 1. 队列组 可以使用GC…

探索开源的容器引擎--------------Docker容器操作

目录 一、Docker 容器操作 1.1容器创建 1.2查看容器的运行状态 1.3启动容器 1.4创建并启动容器 1.4.1当利用 docker run 来创建容器时&#xff0c; Docker 在后台的标准运行过程是&#xff1a; 1.4.2在后台持续运行 docker run 创建的容器 1.4.3创建容器并持续运行容器…

Swift-27-类的初始化与销毁

Swift的初始化是一个有大量规则的固定过程。初始化是设置类型实例的操作&#xff0c;包括给每个存储属性初始值&#xff0c;以及一些其他准备工作。完成这个过程后&#xff0c;实例就可以使用了。 简单来讲就是类的构造函数&#xff0c;基本语法如下&#xff1a; 注意&#xff…

3节点ubuntu24.04服务器docker-compose方式部署高可用elk+kafka日志系统并接入nginx日志

一&#xff1a;系统版本: 二&#xff1a;部署环境&#xff1a; 节点名称 IP 部署组件及版本 配置文件路径 机器CPU 机器内存 机器存储 Log-001 10.10.100.1 zookeeper:3.4.13 kafka:2.8.1 elasticsearch:7.7.0 logstash:7.7.0 kibana:7.7.0 zookeeper:/data/zookeep…

贪心算法在单位时间任务调度问题中的应用

贪心算法在单位时间任务调度问题中的应用 一、引言二、问题描述与算法设计三、算法证明四、算法实现与效率分析五、C语言实现示例六、结论 一、引言 单位时间任务调度问题是一类经典的优化问题&#xff0c;旨在分配任务到不同的时间槽中&#xff0c;使得某种性能指标达到最优。…

【JAVA】UDP与TCP套接字编程

目录 一、UDP数据报套接字编程 1、DatagramSocket API 2、DatagramPacket API 3、InetSocketAddress API 4、示例一 5、示例二 二、TCP流套接字编程 1、ServerSocket API 2、Socket API 3、TCP中的长短连接 4、示例一 5、示例二 一、UDP数据报套接字编程 1、Datag…

《ElementPlus 与 ElementUI 差异集合》el-select 显示下拉列表在 Cesium 场景中无法监听关闭

前言 仅在 Element UI 时有此问题&#xff0c;Element Plus 由于内部结构差异较大&#xff0c;不存在此问题。详见《el-select 差异点&#xff0c;如&#xff1a;高、宽、body插入等》&#xff1b; 问题 点击空白处&#xff0c;下拉列表可监听并关闭&#xff1b;但在 Cesium…

图解《图搜索算法》及代码实现

关注我&#xff0c;持续分享逻辑思维&管理思维&#xff1b; 可提供大厂面试辅导、及定制化求职/在职/管理/架构辅导&#xff1b; 有意找工作的同学&#xff0c;请参考博主的原创&#xff1a;《面试官心得--面试前应该如何准备》&#xff0c;《面试官心得--面试时如何进行自…

Jmeter之Beanshell详解

一、 Beanshell概念 Beanshell: BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法;BeanShell是一种松散类型的脚本语言(这点和JS类似);BeanShell是用Java写成的,一个小型的、免费的、可以下载的、嵌入式的Java源代码解释器,具有对象脚本语言特性…

LayuiMini使用时候初始化模板修改(下载源码)

忘记加了 下载 地址 &#xff1a; layui-mini: layuimini&#xff0c;后台admin前端模板&#xff0c;基于 layui 编写的最简洁、易用的后台框架模板。只需提供一个接口就直接初始化整个框架&#xff0c;无需复杂操作。 LayuiMini使用时候初始化模板官网给的是&#xff1a; layu…

用Excel做一个功能完备的仓库管理系统

1 基本设计思路 用到的Excel技术&#xff1a;sumif, vlookup, 表格(table)。基本思路&#xff1a;在有基础的商品、仓库等信息的情况下&#xff0c;对商品的每一个操作都有对应的单据&#xff0c;然后再汇总统计。标识&#xff1a;为了在不同的维度统计数量&#xff0c;各单据…

国产FTP文件传输服务器需要具备哪些关键特性?

国产FTP文件传输服务器是指根据中国国内信息技术创新&#xff08;信创&#xff09;的要求和标准&#xff0c;自主研发的文件传输服务器软件。这类软件旨在替代传统的FTP服务器&#xff0c;以更好地适应国产化和信息安全的需要。国产FTP文件传输服务器通常需要具备以下要求&…

图书租赁系统-扣费服务

resources中添加moment.js文件。 然后引入moment.js文件&#xff1a; <script src"/js/moment.js"></script>借阅结束时间选完后changeDate事件&#xff1a; $("input[nameendTime]").datetimepicker({format: "yyyy-mm-dd hh:ii",…

Linux:进程与计划任务

文章目录 Linux&#xff1a;进程与计划任务一、进程1、进程是什么2、进程状态 二、列出进程命令1、查看静态的进程统计信息——“ps”Play1&#xff1a;“ps aux”Play2:ps -elf 2、查看静态的进程统计信息——“top”段首解析进程信息区解释 三、运行与终止进程3.1、运行进程3…