【Linux基础(二)】进程管理

news2024/10/23 22:22:58

学习分享

  • 1、程序和进程
    • 1.1、程序
    • 1.2、进程和进程ID
  • 2、Linux下的进程结构
  • 3、init进程
  • 4、获取进程标识
  • 5、fork系统调用
    • 5.1、fork函数实例分析
  • 6、进程的特性
  • 7、在Linux下进程指令
    • 7.1、终止进程指令
    • 7.2、查看进程指令:
    • 7.3、以树状图列出进程
  • 8、多进程运行异常情况
    • 8.1、孤儿进程
    • 8.2、僵尸进程
    • 8.3、解决方案
      • 8.3.1、wait和waitpid函数
        • 8.3.1.1、wait函数
        • 8.3.1.2、waitpdi函数
        • 8.3.1.3、wait和waitpid的区别
      • 8.3.2、wait函数解决孤儿进程
      • 8.3.3、wait函数解决僵尸进程
    • 8.4、进程退出码传递示例
  • 9、子进程结束的方式

1、程序和进程

1.1、程序

程序(program)是存放在磁盘文件中的可执行文件。

1.2、进程和进程ID

程序的执行实例被称为进程(process)。本书的每一页几乎都会使用这一术语。内核观点:分配系统资源(CPU,内存)的实体。

每个linux进程都一定有一个唯一的数字标识符,称为进程PID(process ID)。进程ID总是一非负整数。

使用指令:ps ajx

在这里插入图片描述

2、Linux下的进程结构

在这里插入图片描述

操作系统将.exe文件从磁盘搬到内存后被CPU处理,os内可能存在多个进程,此时操作系统就要管理好这些进程。操作系统将可执行程序的各种数据提取出来,在创建一个结构体把数据存进去,由于同时会存在多个进程,所以操作系统使用链表或其他数据结构将它们链接在一起。

PCB(进程控制块)是这个结构体的总称,在Linux系统下,PCB具体叫做:struct task_struct‘

3、init进程

进程ID为1通常是init进程,在自举过程结束时由内核调用。
init进程绝不会终止。
它是一个普通的用户进程(与交换进程不同,它不是内核中的系统进程),但是它以超级用户特权运行。

4、获取进程标识

在这里插入图片描述

#include <iostream>
#include <sys/types.h>
#include <unistd.h>
using namespace std;

int main()
{
	pid_t pid =getpid();
	
	while(1)
	{
		cout<<"pid = "<<pid<<endl;
		sleep(1);
	}
	return 0;
]

5、fork系统调用

在这里插入图片描述
在这里插入图片描述

由fork创建的新进程被称为子进程( child process)。
该函数被调用一次,但返回两次。两次返回的区别是子进程的返回值是0,而父进程的返回值则是子进程的进程ID。
一般来说,在f o r k之后是父进程先执行还是子进程先执行是不确定的。这取决于内核所使用的调度算法。

在这里插入图片描述

#include <iostream>
#include <sys/types.h>
#include <unistd.h>
using namespace std;

int main()
{
	pid_t pid;
	int number =0 ;
	cout <<"main 函数主进程 pid = "<<getpid()<<endl;
	//创建新的子进程
	pid =fork();
	if(pid ==0)
	{
		while(1)
		{
			cout<<"pid = "<<pid<<"自己 getpid ="<<getpid()<<"父进程为:"<<getppid()<<end;
			number++;
			cout<<"number"<<number<<endl;
			sleep(1);
		}
	}
	else if(pid > 0)
	{
		while(1)
		{
			cout<<"pid = "<<pid<<"getpid ="<<getpid()<<end;
			numbe++;
			cout<<"number"<<number<<endl;
			sleep(1);
		}
	}
	return 0;
]

5.1、fork函数实例分析

#include <iostream>
#include <sys/types.h>
#include <unistd.h>
using namespace std;

int main()
{
	pid_t pid;
	forint i =0;i<2;i++{
		pid =fork();
		cout<<"pid = "<<pid <<"当前进程 ID = "<<getpid()<<endl;
	}
	return 0;
]

在这里插入图片描述

6、进程的特性

1、操作系统分配资源的基本单位
2、一个操作系统下的多个进程是同时运行
3、多个进程的运行,是随机的,代码无法决定进程执行顺序,只能做到进程创建、结束
4、多个进程之间不会相互影响,它们各自有属于自己的PCB(代码段、数据段、堆栈段)
5、多个进程之间不能共享数据(IPC技术才能解决数据互通、共享)

7、在Linux下进程指令

7.1、终止进程指令

在我们的程序运行时,可以在运行的地方按CTRL+C来结束进程,但是还有一种方法可以结束进程:

使用指令:kill -9 要杀掉的进程ID

(注:这里的-9是信号参数,直接使用即可)

7.2、查看进程指令:

ps -aux

7.3、以树状图列出进程

pstree

8、多进程运行异常情况

8.1、孤儿进程

父进程比子进程先结束,这个子进程称为孤儿进程。
孤儿进程的父进程统一转变为1号进程,这个1号进程实际上就是操作系统本身!


#include <iostream>
#include <sys/types.h>
#include <unistd.h>
using namespace std;

int main()
{
	pid_t pid;
	cout <<"main 函数主进程 pid = "<<getpid()<<endl;
	//创建新的子进程
	pid =fork();
	if(pid ==0)
	{
		for(int i=0;i<30;i++)
		{
			cout<<"自己 getpid ="<<getpid()<<" i= "<<i<<end;
			sleep(1);
		}
	}
	else if(pid > 0)
	{
		for(int i=0;i<15;i++)
		{
			cout<<"父进程 getpid ="<<getpid()<<"i = "<<i<<end;
			sleep(1);
		}
	}
	return 0;
]

8.2、僵尸进程

子进程比父进程先结束,子进程逻辑走完,但是占用资源(资源还没有释放)。

  • 若一个进程长期处于z状态(僵尸状态),不及时回收,此时会有内存泄漏的风险!

当一个子进程结束运行时,它与其父进程之间的关联还会保持到父进程也正常地结束运行或者父进程调用了wait才告终止。
进程表中代表子进程的数据项是不会立刻释放的,虽然不再活跃了,可子进程还停留在系统里,因为它的退出码还需要保存起来以备父进程中后续的wait调用使用。它将称为一个“僵尸进程”。


#include <iostream>
#include <sys/types.h>
#include <unistd.h>
using namespace std;

int main()
{
	pid_t pid;
	cout <<"main 函数主进程 pid = "<<getpid()<<endl;
	//创建新的子进程
	pid =fork();
	if(pid ==0)
	{
		for(int i=0;i<15;i++)
		{
			cout<<"自己 getpid ="<<getpid()<<" i= "<<i<<end;
			sleep(1);
		}
	}
	else if(pid > 0)
	{
		for(int i=0;i<30;i++)
		{
			cout<<"父进程 getpid ="<<getpid()<<"i = "<<i<<end;
			sleep(1);
		}
	}
	return 0;
]

8.3、解决方案

  • 子进程exit 父进程wait

8.3.1、wait和waitpid函数

当一个进程正常或异常终止时,内核就向其父进程发送SIGCHLD信号。因为子进程终止是个异步事件(这可以在父进程运行的任何时候发生),所以这种信号也是内核向父进程发的异步通知。父进程可以忽略该信号,或者提供一个该信号发生时即被调用执行的函数(信号处理程序)。对于这种信号的系统默认动作是忽略它。
wait函数用于使父进程阻塞,直到一个子进程结束或者该进程接收到一个指定信号为止。

在这里插入图片描述

8.3.1.1、wait函数

函数说明
在这里插入图片描述
wait返回状态检测
在这里插入图片描述

8.3.1.2、waitpdi函数

函数说明
在这里插入图片描述

8.3.1.3、wait和waitpid的区别

在这里插入图片描述

8.3.2、wait函数解决孤儿进程


#include <iostream>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
using namespace std;

int main()
{
	int status =0;
	pid_t pid;
	cout <<"main 函数主进程 pid = "<<getpid()<<endl;
	//创建新的子进程
	pid =fork();
	if(pid ==0)
	{
		for(int i=0;i<30;i++)
		{
			cout<<"自己 getpid ="<<getpid()<<" i= "<<i<<end;
			sleep(1);
		}
	}
	else if(pid > 0)
	{
		for(int i=0;i<15;i++)
		{
			cout<<"父进程 getpid ="<<getpid()<<"i = "<<i<<end;
			sleep(1);
		}
		wait(&status);
	}
	return 0;
]

8.3.3、wait函数解决僵尸进程


#include <iostream>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
using namespace std;

int main()
{
	int status =0;
	pid_t pid;
	cout <<"main 函数主进程 pid = "<<getpid()<<endl;
	//创建新的子进程
	pid =fork();
	if(pid ==0)
	{
		for(int i=0;i<15;i++)
		{
			cout<<"自己 getpid ="<<getpid()<<" i= "<<i<<end;
			sleep(1);
		}
		exit(0);
	}
	else if(pid > 0)
	{
		wait(&status);//阻塞函数  等待某一个事件发生   等待子进程exit传递退出码
		for(int i=0;i<30;i++)
		{
			cout<<"父进程 getpid ="<<getpid()<<"i = "<<i<<end;
			sleep(1);
		}
		
	}
	return 0;
]

8.4、进程退出码传递示例


#include <iostream>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
using namespace std;

int main()
{
	int status =0;
	pid_t pid;
	cout <<"main 函数主进程 pid = "<<getpid()<<endl;
	//创建新的子进程
	pid =fork();
	if(pid ==0)
	{
		for(int i=0;i<15;i++)
		{
			cout<<"自己 getpid ="<<getpid()<<" i= "<<i<<end;
			sleep(1);
		}
		exit(0);
	}
	else if(pid > 0)
	{
		wait(&status);//阻塞函数  等待某一个事件发生   等待子进程exit传递退出码
		cout<<"status="<<status<<endl;
		//判断子进程是否结束
		if(WIFEXITED(status)>0)
		{
			cout<<"退出码"<<WEXITSTATUS(status)<<endl;
		}
		for(int i=0;i<30;i++)
		{
			cout<<"父进程 getpid ="<<getpid()<<"i = "<<i<<end;
			sleep(1);
		}
		
	}
	return 0;
]

9、子进程结束的方式

  • 1、return;
  • 2、break;
  • 3、exit(0);

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

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

相关文章

判断连续数据同意特征的方法:插旗法

bool isMonotonic(int* nums, int numsSize) {int flag 2;for (int i 1; i < numsSize; i) {if (nums[i-1] > nums[i]) {if (flag 0)return false;flag 1;}else if (nums[i-1] < nums[i]) {if (flag 1)return false;flag 0;}}return true; }此代码较为简单&…

Vue中如何处理组件间的耦合问题?

在Vue中处理组件间的耦合问题是前端开发中常见的挑战之一。耦合问题指的是组件之间的依赖关系过于紧密&#xff0c;一旦某个组件发生改动&#xff0c;则可能导致其它组件也需要作出相应调整。为了解决这个问题&#xff0c;我们可以采取以下几种方法&#xff1a; 使用事件总线&…

牛客每日一题之 前缀和

目录 题目介绍&#xff1a; 算法原理&#xff1a; 前缀和&#xff1a; 代码实现&#xff1a; 题目介绍&#xff1a; 题目链接&#xff1a;【模板】前缀和_牛客题霸_牛客网 算法原理&#xff1a; 先讲讲暴力解法每次求出数组下标r之前元素的和&#xff0c;再减去数组下标l-…

Docker容器的操作

目录 运行容器 查看容器 查看容器详细信息 删除容器 启动容器 停止容器 重启容器 暂停容器 激活容器 杀死容器 进入容器 常用 查看容器的日志 拷贝容器的文件到本地 容器改名 查看容器资源 查看容器内部的进程 监测容器发生的事件 检测容器停止以后的反回值…

vue3 + vite全局引入element-plus后使用 Message 消息提示

安装Element plus&#xff1a; pnpm install element-plus 安装unplugin-element-plus 自动导入组件 pnpm i -D unplugin-auto-import pnpm install -D unplugin-element-plus vite.config.ts 使用plugins数组里配置&#xff0c;自动导入 import { fileURLToPath, URL } fro…

【应用多元统计分析】--多元数据的描述和展示(R语言)

一元随机变量 我们用协方差来刻画两个变量的相关关系&#xff0c;这里指的是线性相关关系。 对于一元随机变量的可视化最简单的就是散点图&#xff0c;大致可以看出X和Y之间的相关关系。如果想更好的看X、Y之间的相关关系&#xff0c;可以画二维的散点图。 总结&#xff1a; 均…

蓝桥杯物联网竞赛_STM32L071_11_知识体系的查漏与补缺

太久没学单片机了&#xff0c;再重新过一遍查漏补缺&#xff0c;对其中之前没怎么在意的&#xff0c;而现在又发觉的问题进行再分析与补充 1. debug serial wire是干什么用的 这个东西我勾选不勾选都对我的程序没有什么影响&#xff0c;我很好奇是干什么用的&#xff0c;网上查…

【PCIe】初识PCIe

&#x1f525;博客主页&#xff1a;[PannLZ] &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 文章目录 PCIe简介PCIe速度 PCIe简介 计算机内部有很多电子元器件&#xff0c;他们之间会有数据沟通和传输的需求。如果A元件想给B元件传输数据&am…

JavaWeb04-Request,Response

目录 一、Request&#xff08;请求&#xff09; 1.作用 2.继承体系 3.获取请求数据 &#xff08;1&#xff09;请求行 &#xff08;2&#xff09;请求头 &#xff08;3&#xff09;请求体&#xff08;POST&#xff09; &#xff08;5&#xff09;Request通用方式获取请求…

Unity用Shader将一张图片变成描边图片素描风格。

环境&#xff1a; unity2021.3.x 效果&#xff1a; 实现核心思路(shader)&#xff1a; fixed4 frag (v2f i) : SV_Target {fixed4 col tex2D(_MainTex, i.uv);// 调整相似度bool isRedMatch abs(col.r - _TargetColor.r) < 0.15;bool isGreenMatch abs(col.g - _Target…

消息队列-Kafka-如何进行顺序消费

全局有序 只有 1 个分区&#xff0c;那这个时候就是能够保证消息的顺序消费。 分区有序 如果我们还是想同时消费多个分区并且保证有序&#xff0c;这个时候我们需要将需要保证顺序的消息路由到同一个分区。 在发送消息的时候我们可以看到&#xff1a; 上面的代码定义了消息…

【R语言实战】聚类分析及可视化

&#x1f349;CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一&#xff5c;统计学&#xff5c;干货分享          擅长Python、Matlab、R等主流编程软件          累计十余项国家级比赛奖项&#xff0c;参与研究经费10w、40w级横向 文…

【自然语言处理】BitNet b1.58:1bit LLM时代

论文地址&#xff1a;https://arxiv.org/pdf/2402.17764.pdf 相关博客 【自然语言处理】【大模型】BitNet&#xff1a;用1-bit Transformer训练LLM 【自然语言处理】BitNet b1.58&#xff1a;1bit LLM时代 【自然语言处理】【长文本处理】RMT&#xff1a;能处理长度超过一百万t…

【Vue】sessionStorage存取数据

一. 需求 1.1 模板 Vab Admin Pro 1.2 组件 ElementUI 1.3 阐述 列表页面搜索【关键词】点击【查询】后&#xff0c;点击【查看】按钮跳转到【详情页】&#xff0c;详情页【返回】【保留原搜索关键词】 原图 搜索查询【关键词】 详情 返回后【保留】【搜索查询关键词…

一次简单操作代替所有异常处理

一、背景 在服务端处理前端发过来的响应的时候&#xff0c;开发者不可能穷尽用户的所有奇怪的操作。除此之外&#xff0c;我们还需要应付前端人员对我们的无情吐槽&#xff0c;你对XXXX请求返回的为啥是奇怪的响应数据呢&#xff1f;于是全局异常处理应运而生&#xff0c;一次处…

Java面试篇【并发编程·进阶】常见面试题(2024最新)

并发常见面试题进阶 1.synchronized synchronized关键字解决的是多线程之间访问资源的同步性&#xff0c;synchronized关键字可以保证被它修饰的方法或者代码块在任意时刻只能被一个线程执行。 监视器锁&#xff08;monitor&#xff09;是依赖于底层的操作系统的 Mutex Lock来…

回溯算法07-子集(Java/子集问题)

.子集 题目描述 给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的子集&#xff08;幂集&#xff09;。解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[],[…

通过vue ui创建项目

确认前端环境都安装好之后 打开黑窗口 输入 vue ui 会打开一个vue的网页 在此创建项目 可以选择在那个路径创建 这是我的项目配置 这里是选择vue版本 我要用的是vue2 选好点击创建项目就好了 创建好后的重点的目录结构以及结构的作用 启动前端工程 将创建好的项目导入编译器 我…

自动化测试po模式是什么?自动化测试po分层如何实现?

一、什么是PO模式 全称&#xff1a;page object model 简称&#xff1a;POM/PO PO模式最核心的思想是分层&#xff0c;实现松耦合&#xff01;实现脚本重复使用&#xff0c;实现脚本易维护性&#xff01; 主要分三层&#xff1a; 1.基础层BasePage&#xff1a;封装一些最基…

通义灵码-智能编码辅助工具

1.介绍 通义灵码&#xff0c;是阿里云出品的一款基于通义大模型的智能编码辅助工具&#xff0c;提供行级/函数级实时续写、自然语言生成代码、单元测试生成、代码注释生成、代码解释、研发智能问答、异常报错排查等能力&#xff0c;并针对阿里云 SDK/OpenAPI 的使用场景调优&a…