<Linux>进程

进程

文章目录

  • 进程
    • PCB
    • pid与ppid
    • fork系统调用
    • 进程状态
    • 孤儿进程
    • 状态优先级
    • 环境变量
    • 进程地址空间
    • 虚拟地址

最直观的表示:启动一个软件,本质就是启动一个进程

PCB

PCB是Process Control Block的简称,是用来描述进程状态信息的数据结构。

进程运行时,是会在内存中存放该进程的代码+数据

因此:进程=代码和数据+PCB

这里的PCB结构是一种泛化的概念,在Linux下,PCB的实例化就是task_struct

pid与ppid

就像人有名字一样,进程也有自己的名字,进程的名字就是pid,ppid就是该进程的父进程的pid

fork系统调用

fork是创建进程的系统调用,给父进程返回子进程pid,给子进程返回0

#include<stdio.h>
#include<sys/types.h>int main()
{pid_t id =fork();if(0!=id){printf("我是父进程,pid:%d 我的子进程pid:%d\n",getpid(),id);//getpid()返回pid}else if(0==id){printf("我是子进程,pid:%d 我的父进程pid:%d\n",getpid(),getppid());//getppid()返回父进程pid}return 0;
}

运行结果如下
在这里插入图片描述

注意

  • fork之后会有两个不同的执行流,至于父进程对于执行流先运行还是子进程对于执行流先运行不一定,这由操作系统的调度器决定
  • fork之后代码由父子进程共享

fork之后子进程会拷贝父进程的代码与数据给自己,操作系统会给子进程创建对应的PCB。

进程状态

  • 运行态,这里的运行态不单单指在cpu上运行才叫做运行态,在运行队列中排队等待调度器调度时也叫做运行态
  • 阻塞,阻塞态可以简单地理解为进程等待某种资源的释放或某种事件的发生,进程在这种状态下暂时停止执行,直到所需的资源可用或所等待的事件发生为止。
  • 挂起,内存不足时,操作系统会适当置换进程的代码与数据到磁盘,这种状态就叫做挂起状态。

Linux下的进程状态

  • R:就是上面运行态

验证R状态

#include <stdio.h>int main()
{while (1){}return 0;
}

运行起来之后写一段shell脚本来检测进程运行状态

while :;do  ps axj | head -1 && ps axj | grep test | grep -v grep ; sleep 1 ;echo "------------------"; done

在这里插入图片描述

R后面的‘+’表示这是一个前台进程

  • S:对于上面阻塞态,可被操作系统唤醒,可中断睡眠

验证S状态

#include <stdio.h>int main()
{int a;scanf("%d", &a);return 0;
}

运行起来之后,系统会等着你输入,这时候不要输入,去查看进程状态

在这里插入图片描述

  • D:深度睡眠,不可被中断,不可被被动唤醒

不做验证

  • T:暂停状态

在用一些调试工具调试时可以验证,这里不做验证

  • Z:僵尸状态,进程已经退出,但是还不允许操作系统释放,处于被检测的状态。维持该状态是为了父进程/操作系统来回收

验证Z状态

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
int main()
{pid_t id = fork();if (0 == id){int cnt = 3;while (cnt--){printf("我是子进程,pid:%d,ppid:%d\n", getpid(), getppid());sleep(1);}exit(0);}else{while (1){printf("我是父进程,pid:%d,ppid:%d\n", getpid(), getppid());sleep(1);}}return 0;
}

可以看到,前面三秒都是S装态,这里S状态是因为sleep了一秒钟,第四秒开始子进程变成僵尸状态,等待着父进程或者操作系统来回收,也就是对应的Z状态

在这里插入图片描述

子进程的进程名后面出现了‘defunct’,即为失效的,即僵尸状态

在这里插入图片描述

打印输出也只剩父进程

如何解决僵尸进程?在我的另一篇博客:中有详细解读,感兴趣的朋友可以自行阅读。

  • X:终止状态

孤儿进程

父进程先退出,子进程就被称为孤儿进程,此时该进程就会被init进程(pid为1)领养,由init回收

验证孤儿进程

// 验证孤儿进程
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>int main()
{pid_t id = fork();if (0 == id){while (1){printf("我是子进程,pid:%d,ppid:%d\n", getpid(), getppid());sleep(1);}}else{int cnt = 3;while (cnt--){printf("我是父进程,pid:%d,ppid:%d\n", getpid(), getppid());sleep(1);}exit(0);}return 0;
}

在这里插入图片描述

可以看到,前三秒父进程和子进程同时在跑,但是3秒后父进程退出,子进程被1号进程领养

状态优先级

进程优先级即cpu资源分配的先后顺序

查看进程优先级命令

ps -l

在这里插入图片描述

  • PRI

代表进程优先级,数值越小,优先级越高

  • NI

nice值,用来更改进程优先级,取值范围[-20,19]

PRI=PRI+NI

所以想要修改进程优先级,就要通过修改nice值来进而修改进程优先级

修改进程优先级命令

top

输入‘r’后输入进程pid,随后修改nice值即可

环境变量

先来看现象

我们写一个打印的程序

#include <stdio.h>
int main()
{printf("hello linux\n");return 0;
}

在这里插入图片描述

使用系统自带的命令时,不用带路径,直接可以运行,但是我们自己写的程序如果不带路径就会报错。

这就和环境变量有关

查看环境变量

echo $PATH

在这里插入图片描述

这里维护了大量的路径,路径之间用冒号’:‘隔开,我们使用的诸如’ls’,'pwd’的系统命令就在这些路径当中,我们可以查看一下ls所处的路径

which ls

在这里插入图片描述

所以我们运行自己的程序时,shell会在这些路径中去查找’myproc’,没有找到就会显示’command not found’

如果不想带路径运行自己的程序,可以将可执行程序所在的路径导入到系统环境变量中,即可像系统指令一样执行自己写的程序。

export PATH=$PATH:程序所在路径

在这里插入图片描述

导入之后再查看系统环境变量,这时程序即可直接运行,不用带路径

但是,这种方式只在本次对话当中有用,下次连接系统时不会存在这个路径,如果需要永久保存,需要修改环境变量配置文件。

但是呢,环境变量不止PATH,还有HOME

echo $HOME

在这里插入图片描述

SHELL环境变量

echo $SHELL

在这里插入图片描述

显示所有环境变量

env
  • 子进程的环境变量继承自父进程,往上层去找最终就是bash的环境变量
  • 环境变量具有全局属性,体现在可以被子进程继承

进程地址空间

在c/c++程序员眼中,程序地址空间如下

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
int uninit_global;
int init_global = 10;int main(int argc, char *argv[], char *env[])
{const char *str = "read only";int *heap1 = (int *)malloc(sizeof(int));int *heap2 = (int *)malloc(sizeof(int));printf("code address:%p\n", main);printf("read only address:%p\n", str);printf("init_global address:%p\n", &init_global);printf("uninit_global address:%p\n", &uninit_global);printf("head address:%p\n", heap1);printf("head address:%p\n", heap2);printf("stack address:%p\n", &heap1);printf("stack address:%p\n", &heap2);int i = 0;for (i = 0; i < argc; i++){printf("argv[%d] address:%p\n", i, &argv[i]);}for (i = 0; env[i]; i++){printf("env[%d]:%p\n", i, env[i]);}return 0;
}

输入命令运行结果如下

在这里插入图片描述

虚拟地址

为什么叫虚拟地址空间?难道上面我们讲的进程地址空间都是虚拟的?假的? 没错!!就是假的!!

如果直接让用户对真实的 物理空间进行读写访问,其实是非常危险的动作,因此,操作系统不会让你直接访问真实的物理地址。

操作系统表面上告诉进程,计算机的地址空间全是你的,但是其实不然。

先来一段代码

#include <stdio.h>
#include <sys/types.h>int global = 10;int main()
{pid_t id = fork();if (0 == id){printf("global_val:%d---%p\n", global, &global);}else{global = 5;printf("global_val:%d---%p\n", global, &global);}return 0;
}

运行结果如下

在这里插入图片描述

出现了非常神奇的现象?同一个地址为什么对应的值不同???

我们知道,父进程在创建子进程之后会给子进程拷贝一份父进程的代码与数据,也会给子进程创建对应的程序地址空间,而这个程序地址空间就属于虚拟地址,需要页表哈希索引来找到对应的真实的物理地址,子进程拷贝的虚拟地址与父进程对应的虚拟地址一样,所以出现了地址一样,值却不一样的现象。解析图如下

在这里插入图片描述

上述程序因为拷贝了父进程的代码与数据,拷贝的地址属于虚拟地址,经过页表置换后才能找到真正的物理地址。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp开发微信小程序问题汇总

1. 自定义校验规则validateFunction失效 2. 微信小程序不支持<Br>换行 在 <text></text> 标签中使用\n(必须 text 标签&#xff0c;view 标签无效 ) 3. 微信小程序无法使用本地静态资源图片的解决方法 (1) 将图片上传到服务器&#xff0c;小程序访问该图片…

springboot与flowable(9):候选人组

act_id_xxx相关表存储了所有用户和组的数据。 一、维护用户信息 Autowiredprivate IdentityService identityService;/*** 维护用户*/Testvoid createUser() {User user identityService.newUser("zhangsan");user.setEmail("zhangsanqq.com");user.setF…

Java_异常

什么是异常&#xff1f; 异常就是代表程序出现问题 Error&#xff1a;代表系统级别的错误&#xff08;属于严重问题&#xff09;&#xff0c;也就是说系统一旦出现问题&#xff0c;sun公司会把这些问题封装成Error对象给出来&#xff0c;说白了&#xff0c;Error是给sun公司自…

02_01_SpringMVC初识

一、回顾MVC三层架构 1、什么是MVC三层 MVC是 模型&#xff08;Model&#xff09;、视图&#xff08;View&#xff09;、控制器&#xff08;Controller&#xff09;的简写&#xff0c;是一种软件设计规范。主要作用是降低视图与业务逻辑之间的双向耦合&#xff0c;它不是一种…

android 播放视频

播放视频文件 新建一个activity_main.xml文件&#xff0c;文件中放置了3个按钮&#xff0c;分别用于控制视频的播放、暂停和重新播放。另外在按钮的下面又放置了一个VideoView&#xff0c;稍后的视频就将在这里显示。 <LinearLayout xmlns:android"http://schemas.an…

大模型应用:LangChain-Golang核心模块使用

1.简介 LangChain是一个开源的框架&#xff0c;它提供了构建基于大模型的AI应用所需的模块和工具。它可以帮助开发者轻松地与大型语言模型(LLM)集成&#xff0c;实现文本生成、问答、翻译、对话等任务。LangChain的出现大大降低了AI应用开发的门槛&#xff0c;使得任何人都可以…

爬虫可以不必自己写,使用ChatGPT编写抓取电影评论数据脚本

经常去新华书店看看有没有什么新书上架&#xff0c;还是更新挺及时的&#xff0c;可以反映新的技术趋势。这不&#xff0c;最近就看到了这本《巧用 ChatGPT 快速搞定数据分析》&#xff0c;作者是个大牛&#xff0c;第一次看到prompt可以这么写&#xff0c;得写这么长&#xff…

网络协议,OSI,简单通信,IP和mac地址

认识协议 1.讲故事 2004年&#xff0c;小明因为给他爹打电话&#xff08;座机&#xff09;费用太贵&#xff0c;所以约定一种信号&#xff0c;响一次是报平安&#xff0c;响两次是要钱&#xff0c;响三次才需要接通。 2.概念 协议&#xff1a;是一种约定&#xff0c;这种约…

14. RTCP 协议

RTCP 协议概述 RTCP&#xff08;Real-time Transport Control Protocol 或 RTP Control Protocol 或简写 RTCP&#xff09;&#xff0c;实时传输控制协议&#xff0c;是实时传输协议&#xff08;RTP&#xff09;的一个姐妹协议。 注&#xff1a;RTP 协议和 RTP 控制协议&#…

新版嘎嘎快充互联互通系统配置文档

宝塔环境配置 登录宝塔账号&#xff0c;安装nginx、mysql5.7、php7.2、supervisor、redisphp安装扩展&#xff1a; 1&#xff09;安装swooleloader72 将嘎嘎官方提供的swoole_loader_72_nts.so文件上传到 /www/server/php/72/lib/php/extensions/no-debug-non-zts-20170718…

【Tkinter界面】Canvas 图形绘制(03/5)

文章目录 一、说明二、画布和画布对象2.1 画布坐标系2.2 鼠标点中画布位置2.3 画布对象显示的顺序2.4 指定画布对象 三、你应该知道的画布对象操作3.1 什么是Tag3.2 操作Tag的函数 https://www.cnblogs.com/rainbow-tan/p/14852553.html 一、说明 Canvas&#xff08;画布&…

重塑IT审计的未来:数智化审计赋能平台的创新与实践

重塑IT审计的未来&#xff1a;数智化审计赋能平台的创新与实践 一、当前企业开展IT审计面临的挑战 随着信息技术的快速发展、企业数字化转型的持续深入&#xff0c;以及网络安全合规要求的不断增强&#xff0c;企业开展新型IT审计重要性越来越突出&#xff0c;但实施难度却越来…

阿里新发布的UniAnimate现高效人像动画生成;在ComfyUI中使用Stable 3模型;音频版的gpt2o;将 PDF 文档转换为音频播客

✨ 1: UniAnimate 阿里新发布的UniAnimate通过统一的视频扩散模型&#xff0c;实现高效人像动画生成&#xff0c;支持长视频生成 UniAnimate 是一种专注于一致性人像动画生成的统一视频扩散模型。该模型通过映射参考图像、姿势指导和噪声视频到一个共同特征空间&#xff0c;实…

Docker笔记-Debian容器内搭建ssh服务

登陆容器之后修改密码&#xff1a; passwd 密码设置完成后安装openssh-server apt-get install openssh-server 修改端口号为50022并添加配置 vim /etc/ssh/sshd_config 修改成 Port 50022 PasswordAuthentication yes PermitRootLogin yes 启动 rootlinux:~# /etc/in…

Linux文件与内容查阅、归档压缩

#Linux系统基础 文件与内容查找、归档压缩 find命令搜索文件 grep对文件的内容进行搜索 tar命令进行文件的压缩与解压缩 一、文件的查找 格式实例&#xff1a;find . -name "123.txt"说明find起始目录查找类型查找条件./ 或 .-name“123.txt”在当前目录中查找…

idea打开hierarchy面板

hierarchy&#xff1a;查看类层级关系图 不同版本的IDEA的快捷键不一样&#xff0c;同时如果修改了IDEA快捷键&#xff0c;也可能会不一样&#xff0c;具体查看可通过IDEA上方的Navigate来查看navigate--Type Hierarchy&#xff0c;就可以看见其快捷键了&#xff0c;我的快捷键…

统计信号处理基础 习题解答10-17

题目&#xff1a; 在选择不含信息的或者不假设任何先验知识的先验PDF时,我们需要从数据中得到最大的信息量。在这种方式下,数据是了解未知参数的主要贡献者。利用习题10.15的结果,这种方法可以通过选择使I最大的来实现。对于例10.1的高斯先验PDF,该如何选择和2使得 是不含信息…

【Vue】自学笔记(四)

上一篇&#xff1a;Vue笔记&#xff08;三&#xff09;-CSDN博客 1.VueCli自定义搭建项目 先确保安装了全局工具VueCli 如果没有&#xff0c;则先运行命令 npm i vue/cli -g 选择最后一个自定义搭建项目 选择需要自动搭建的功能 这里我需要router和css预处理器就空格勾选上&…

liunx常见指令

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 二、安装环境 1.租借服务器 2.下载安装 XShell 3.使用xshll登录服务器 三、Linux基础命令 一、文件和命令 ​编辑1、cd 命令 2、pwd 命令 3、ls 命令 4、cp 命令 …

栈的实现详解

目录 1. 栈1.1 栈的概念及结构1.2 栈的实现方式1.3 栈的应用场景 2. 栈的实现2.1 结构体2.2 初始化2.3 销毁2.4 入栈2.5 出栈2.6 获取栈顶元素2.7 判空2.8 获取个数 3. test主函数4. Stack.c文件5. Stack.h文件6. 运行展示 1. 栈 1.1 栈的概念及结构 栈&#xff1a;一种特殊的…