当前位置: 首页 > news >正文

【Linux】进程理解与学习(Ⅰ)

环境:centos7.6,腾讯云服务器
Linux文章都放在了专栏:【Linux】欢迎支持订阅🌹
相关文章推荐:
【Linux】冯.诺依曼体系结构与操作系统

进程概念

什么是进程?

进程是什么?我们打开任务管理器可以看到有很多的程序正在运行状态,并且上面写着进程二字。难道进程就是指这些被运行起来的程序吗?课本上对于进程是这么说的:程序的一个执行实例,正在执行的程序等

windows下的进程

但是实际上这种说法并不完全准确?(举个例子,一个仅仅进入学校的人,并不能算是这个学校的学生,只有这个人的信息被加载到学校的教务系统,并且被这个学校所管理的人,才称得上学生。这里的学校就是指内存,数据只有加载到内存,并被OS所管理,这才算是一个完整的进程)。

os管理进程

在前文我们知道了cpu一般不会与外设进行直接沟通,而是与内存打交道。所以我们在磁盘上的程序被运行时要将数据与代码加载到内存中。由操作系统来进行管理。具体怎么来管理呢?先描述,再组织。

所谓的先描述实际上是指OS会用一个特定的结构体PCB/task_struct)来提取该进程的各种属性(这里的属性与加载到内存中的数据与代码无关,或者说仅仅只有一点点的关系,即可以通过对应的 task_struct找到该进程的代码和数据)。组织是指OS会以链表或者其它的数据结构将各个task_struct组织起来,方便管理。(对进程的修改--->对链表或者其它数据结构的增删查改,比如我们结束一个进程,实际上就是删掉数据结构中对应的pcb

★上面啰嗦一大堆,无非就是说两个事:

  • 结论一进程=os内核关于该进程的相关数据结构(PCB/task_struct)+当前程序加载到内存的代码与数据

  • 结论二OS如何管理进程?先描述(pcb/task_struct),再组织(链表等数据结构)。

PCB — 进程控制块

进程需要被OS管理,管理的本质就是先描述,再组织。而PCB就是用来描述进程的一种特定结构体。在Linux系统下的PCB就是task_struct

task_struct内容分类

task_struct结构体中主要包含了以下信息,了解一下即可:

标示符: 描述本进程的唯一标示符,用来区别其他进程。
状态: 任务状态,退出代码,退出信号等。
优先级: 相对于其他进程的优先级。
程序计数器: 程序中即将被执行的下一条指令的地址。
内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。
I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
其他信息

如何查看进程

第一种方法:通过ps指令

我们输入ps axj就可以查看当前所有进程信息,同时,由于进程信息较多,我们可以利用之前学过的管道,以及grep用来筛选过滤,从而拿到我们想要的进程信息。如下:

第二种方法:通过函数getpid()

在上面task_struct内容中,有一个是标识符,用来区分其他进程。这里的标识符,实际就是指PID每一个进程都有自己的pid,并且每一次运行,pid的值都会发生变化(一般都是逐渐递增,当下一次重新登陆时,又是随机值)。

而我们可以通过系统调用函数getpid()来获取当前进程的pid。我们可以用man手册来查询getpid()的使用。我们可以通过如下的简单代码来验证。

#include<stdio.h>
//头文件包含
#include<unistd.h>
#include<sys/types.h>
int main()
{while(1){//获取当前进程pidprintf("hello world,我的pid:%d\n",getpid());                                             sleep(1);                                                                     }                                                                               return 0;                                                                       } 
第三种方法:在路径/proc下查看

事实上,我们在执行一个程序时,会在/proc目录下生成一个以当前程序的pid命名的目录文件,该目录文件内包含了当前进程的所有信息。并且还有一个特点:当该程序停止运行时,以pid命名的文件会自动销毁

如何中止进程

★三种方法:

  • 我们可以通过指令kill -9进程pid来中止进程

  • 通过热键ctrl c来中止当前进程

  • 通过指令killall 进程名称 来中止进程

三种方式终止进程

父子进程

PPID

进程之间存在父子关系,我们知道,bash是命令行解释器,当我们在命令行输入指令执行一个进程时,我们执行的进程就是bash的子进程。究竟是否如我们所说?我们可以验证一下,当然,在此之前我们要先谈一下PPID,PPID就是当前进程的父进程的pid

fork创建子进程

我们也可以通过系统调用函数fork用来给当前进程创建子进程。我们用man手册查询fork的用法。

我们可以通过如下代码来进行简单测试:

#include<stdio.h>
#include<assert.h>
#include<unistd.h> 
int main()
{//我们用ret来接受fork的返回值pid_t ret=fork();assert(ret!=-1);//断言一下//我们通常使用if语句,用来进行执行流分流if(ret == 0)                            {           while(1){       //此时是子进程,fork给子进程返回0printf("我是子进程,pid:%d,ppid:%d,ret:%d,&ret:%p\n",getpid(),getppid(),ret,&ret);        sleep(1);                                                                         }          }  else if(ret >0){              while(1){       //此时是父进程,fork给父进程返回子进程的pidprintf("我是父进程,pid:%d,ppid:%d,ret:%d,&ret:%p\n",getpid(),getppid(),ret,&ret);sleep(1);                                                                         }          }return 0;}

运行结果

我们发现,确实如此,不过这里有一个疑问,为什么ret的地址相同,但是ret的值却不相同呢?我们从未见过这种现象:同一个变量竟然有两个返回值。这是为什么呢?实际上,我们在函数的最后有一个return 0,而fork之后的代码是父子进程共享的,也就是说,return这个语句被执行了两次,并且当return执行时,函数体内部是已经执行完了的。所以会有两个返回值。

为了验证fork之后的代码,被父子进程共享,我们可以写一个简简单单的代码用来测试一下:

#include<stdio.h>
#include<unistd.h>int main(){int ret = fork();//这里只有一个printfprintf("hello proc,pid:%d,ppid:%d,ret:%d\n", getpid(),getppid(),ret);                          sleep(1);return 0;}

运行结果

我们发现,确实如此。不仅如此,进程还具有独立性,我们可以定义一个全局变量,父进程对

全局变量进行修改,我们发现不会影响到子进程中的那个全局变量。我们也可以进行验证:

#include<stdio.h>
#include<unistd.h>
//定义全局变量
int a=100;
int main(){pid_t ret=fork();if(ret == 0){while(1){//子进程,不对a做修改printf("我是子进程,a=%d,&a=:%p\n",a,&a);sleep(1);}}else {while(1){//父进程,对全局变量a进行修改                                                            a+=100;//假如进程不具有独立性,那么父进程的修改也会影响子进程,究竟会不会呢?printf("我是父进程,a=%d,&a=:%p\n",a,&a);sleep(1);}}return 0;}

结果

我们发现确实如此,不过为什么同一个地址,对内容进行修改却不会互相影响呢?实际上这里的地址并不是真正的物理地址,并且当进程尝试对数据进行修改时,还会触发写时拷贝。(具体放在后面进程地址空间章节详细讲解)。

总结

★上面写了这么多,总结如下:

  • 命令行启动的程序,都会变成bash的子进程

  • 我们可以通过fork为当前进程创建子进程,fork的返回值给子进程返回0,给父进程返回子进程的pid,创建进程失败时返回-1

  • fork之后的代码被父子进程共享(但是谁先运行不确定)

  • 进程具有独立性,父子进程也是如此,对其中一个进程的修改不会影响另一个进程

  • 独立性体现在两方面:1、代码方面是可读的

2、数据方面,当一个执行流尝试修改数据时,OS会给我们的进程触发写时拷贝(后面章节详细讲解)。


end.

生活原本沉闷,但跑起来就会有风!🌹

相关文章:

【Linux】进程理解与学习(Ⅰ)

环境&#xff1a;centos7.6&#xff0c;腾讯云服务器Linux文章都放在了专栏&#xff1a;【Linux】欢迎支持订阅&#x1f339;相关文章推荐&#xff1a;【Linux】冯.诺依曼体系结构与操作系统进程概念什么是进程&#xff1f;进程是什么&#xff1f;我们打开任务管理器可以看到有…...

认识代码之前,请先认识你自己 |《编程人生》

这是我的湛庐课程《给技术人的职场突围课》 &#xff08;链接&#xff09; 的一部分。 这篇文章也是 IT 女神征文活动 的一部分。 《编程人生》是一本优秀程序员的采访集&#xff0c;里面记录了15位世界级编程大师的故事。 我在 发刊词 里面说过&#xff0c;在这个书单课里&am…...

react学习笔记-5:react路由

react旧版本路由 旧版本的路由是按照组件的方式来写的 编写router/index.tsx文件 import App from "../App" import Home from "../views/Home" import About from "../views/About" import { BrowserRouter,Routes,Route } from "react…...

[Python图像处理] 使用高通滤波器实现同态滤波

使用高通滤波器实现同态滤波同态滤波基础实现同态滤波相关链接同态滤波基础 同态滤波是一种去除图像中乘性噪声的技术&#xff0c;常用于校正图像中的不均匀照明。根据图像形成的光照反射模型&#xff0c;图像 f(x,y)f(x,y)f(x,y) 可以由以下两个分量表征&#xff1a; 入射到…...

PyTorch深度学习:60分钟入门

PyTorch深度学习&#xff1a;60分钟入门 本教程的目的: 更高层级地理解PyTorch的Tensor库以及神经网络。训练一个小的神经网络来对图像进行分类。 本教程以您拥有一定的numpy基础的前提下展开 Note: 务必确认您已经安装了 torch 和 torchvision 两个包。 这是一个基于Pytho…...

C语言指针常见问题汇总

我们在学C语言时&#xff0c;指针是我们最头疼的问题之一&#xff0c;针对C语言指针&#xff0c;博主根据自己的实际学到的知识以及开发经验&#xff0c;总结了以下使用C语言指针时常见问题。 1、指针做函数参数 学习函数的时候&#xff0c;讲了函数的参数都是值拷贝&#xf…...

Coremail邮件系统全新上线存档邮箱功能

邮箱积累邮件太多&#xff0c;搜索起来又慢又麻烦&#xff01; 我的重要邮件忘记下载丢失了&#xff01;14天自动删除太难了&#xff01; 有没有可能重要邮件自动存档&#xff0c;解救一下“遗忘星”人&#xff1f; 在我们日常工作中&#xff0c;邮件是最经常使用的办公工具之一…...

Python绘图

1.二维绘图 a. 一维数据集 用 Numpy ndarray 作为数据传入 ply 1. import numpy as np import matplotlib as mpl import matplotlib.pyplot as pltnp.random.seed(1000) y np.random.standard_normal(10) print "y %s"% y x range(len(y)) print "x%s&q…...

【独家】华为OD机试 - 第K个最小码值的字母(C 语言解题)

最近更新的博客 华为od 2023 | 什么是华为od&#xff0c;od 薪资待遇&#xff0c;od机试题清单华为OD机试真题大全&#xff0c;用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析经验分享,题型分享,防作弊指南&#xff09;华为od机试&#xff0c;独家整理 已参加机试…...

整数反转(python)

题目链接&#xff1a; https://leetcode.cn/problems/reverse-integer/ 题目描述&#xff1a; 给你一个 32 位的有符号整数 x &#xff0c;返回将 x 中的数字部分反转后的结果。 如果反转后整数超过 32 位的有符号整数的范围 [−231,231−1][−2^{31}, 2^{31} − 1][−231,231…...

【数据结构】二叉树与堆

文章目录1.树概念及结构1.1树的相关概念1.2树的结构2.二叉树概念及结构2.1相关概念2.2特殊的二叉树2.3二叉树的性质2.4二叉树的存储结构3.二叉树的顺序结构及实现3.1二叉树的顺序结构3.2堆的概念3.3堆的实现Heap.hHeap.c3.4堆的应用3.4.1 堆排序3.4.2 TOP-KOJ题最小K个数4.二叉…...

Git图解-常用命令操作-可视化

目录 一、前言 二、初始化仓库 2.1 设置用户名与邮箱 2.2 初始化仓库 三、添加文件 四、查看文件状态 五、查看提交日志 六、查看差异 七、版本回退 八、删除文件 九、分支管理 9.1 创建分支 9.2 切换分支 9.3 查看分支 9.4 合并分支 十、文件冲突 十一、转视…...

C语言-基础了解-20-typedef

typedef 一、typedef C 语言提供了 typedef 关键字&#xff0c;您可以使用它来为类型取一个新的名字。下面的实例为单字节数字定义了一个术语 BYTE&#xff1a; typedef unsigned char BYTE; 在这个类型定义之后&#xff0c;标识符 BYTE 可作为类型 unsigned char 的缩写&…...

Ubuntu系统升级16.04升级18.04

一、需求说明 作为Linux发行版中的后起之秀&#xff0c;Ubuntu 在短短几年时间里便迅速成长为从Linux初学者到实验室用计算机/服务器都适合使用的发行版&#xff0c;目前官网最新版本是22.04。Ubuntu16.04是2016年4月发行的版本&#xff0c;于2019年4月停止更新维护。很多软件支…...

CM6.3.2启用Kerberos(附问题解决)

基础准备支持JCE的jdk重新安装JCE的jdk(已正确配置跳过)删除/usr/java/下面的jdk,然后通过CM->管理->安全->安装Java无限制...重新安装后,配置Java(可选)主机->主机配置->搜java->Java主目录 配置路径主机->所有主机->设置->高级:Java配置Kerberos安…...

QML 动画(组合动画)

在QML中&#xff0c;可以把多个动画组合成一个单一的动画。 组合动画的类型&#xff1a; ParallelAnimation 动画同时进行&#xff08;并行&#xff09;SequentialAnimation 动画按照顺序执行&#xff08;顺序执行&#xff09;注意&#xff1a;将动画分组为“顺序动画”或“…...

【PHP代码注入】PHP代码注入漏洞

漏洞原理RCE为两种漏洞的缩写&#xff0c;分别为Remote Command/Code Execute&#xff0c;远程命令/代码执行PHP代码注入也叫PHP代码执行(Code Execute)(Web方面)&#xff0c;是指应用程序过滤不严&#xff0c;用户可以通过HTTP请求将代码注入到应用中执行。代码注入(代码执行)…...

Python 常用语句同C/C++、Java的不同

文章目录前言1. 数字 int2. 字符 string3. 列表 List4. 元组 tuple5. 字典 dictionary6. 集合 set7. 值类型变量与引用类型变量8. if elif else9. >、<、>、<、、!10. while11. for前言 本篇为本人前段时间的一个简单汇总&#xff0c;这里可能并不齐全&#xff0c…...

一把火烧掉了苹果摆脱中国制造的幻想,印度制造难担重任

这几年苹果不断推动印度制造&#xff0c;希望摆脱对中国制造的依赖&#xff0c;然而近期苹果在印度的一家代工厂发生大火却证明了苹果的这一计划遭受重大打击&#xff0c;印度制造根本就无法中国制造。一、印度制造屡屡发生幺蛾子苹果推动印度制造已有多年了&#xff0c;然而印…...

常用的 JavaScript 数组 API

以下是一些常用的 JavaScript 数组 API 的代码示例&#xff1a; 1、push() push(): 在数组末尾添加一个或多个元素&#xff0c;返回新的数组长度 const arr [1, 2, 3]; const newLength arr.push(4, 5); console.log(arr); // [1, 2, 3, 4, 5] console.log(newLength); //…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...

WEB3全栈开发——面试专业技能点P4数据库

一、mysql2 原生驱动及其连接机制 概念介绍 mysql2 是 Node.js 环境中广泛使用的 MySQL 客户端库&#xff0c;基于 mysql 库改进而来&#xff0c;具有更好的性能、Promise 支持、流式查询、二进制数据处理能力等。 主要特点&#xff1a; 支持 Promise / async-await&#xf…...