Linux初识进程

Shader Graph入门 Shader Graph 简介 阅读详情

title: 初识进程
date: 2024-07-04 23:02:14
tags: 进程 Linux
cover: https://picbed0521.oss-cn-shanghai.aliyuncs.com/blogpic/PixPin_2024-07-07_23-41-09.png

原文见我的网站: www.supdriver.top


操作系统平台:Linux
服务器系统: CentOS 7


概念抽象

程序

程序 = 代码 + 数据

程序是储存在硬盘上的可执行文件

进程

将程序加载到内存后,就在内存中程序的就是进程。也就是说一个正在运行的程序就能叫做进程

结构关系如下

如图,操作系统为了管理内存中的进程,使用了PCB结构体来描述进程,通过管理PCB来管理进程,依然是先描述再组织

PCB:进程控制块的数据结构(process control block)

所以实际上:进程=PCB+代码和数据

对于代码和数据没什么好说的,接下来主要讨论PCB

task_struct

Linux平台下的PCB叫做task_struct

task_struct内容分类:

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

加粗部分会详细介绍

查看进程

进程的信息可以通过/proc 系统文件夹查看,其中文件夹的名字就是进程的PID

大多数进程信息同样可以使用top和ps这些用户级工具来获取

以我自己编写的一个程序为例

Makefile

mycmd:mycmd.c
	gcc -o $@ $^

.PHONY:clean
clean:
	rm -rf mycmd

注: 后面的程序都是这三个头文件,仅修改main()函数体即可
mycmd.c

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>


int main()
{
  while(1) sleep(1);//死循环使该进程常驻内存
  return 0;
}

然后编译并运行程序
命令行

make
./mycmd
ps aux | grep mycmd | grep -v grep

进程标示符(PID PPID)

可以通过系统接口获取进程标示符

  • 进程id (pid) 使用getpid()
  • 父进程id (ppid) 使用getppid()

来修改一下代码
mycmd.c


int main()
{
  printf("pid: %d\n",getpid());//打印pid (该进程id)
  printf("ppid: %d\n",getppid());//打印ppid (父进程id)
  return 0;
}

命令行

make clean
make
./mycmd

利用fork()创建子进程

mycmd.c


int main()
{
  pid_t id = fork();
  if(id == 0)//子进程
  {
    printf("child pid: %d\n",getpid());//打印pid (该进程id)
    printf("child ppid: %d\n",getppid());//打印ppid (父进程id)
    sleep(1);
  }
  else//父进程
  {
    printf("father pid: %d\n",getpid());//打印pid (该进程id)
    printf("father ppid: %d\n",getppid());//打印ppid (父进程id)
    sleep(1);
  }
  return 0;
}

如图,fork()创建了子进程,且子进程的PPID和父进程PID相同

fork()的返回值

父子进程中fork()函数的返回值(此处用变量id储存)是不同的:

父进程里id的值为子进程的PID,其值>0;子进程里id值固定为0

  • id > 0 父进程
  • id == 0 子进程
  • id < 0 fork()失败

父子进程分流

利用fork()返回值不同的特性可以做到分流操作,利用if...else...让父子进程执行不同的代码

戳我去fork的详细介绍

进程状态

状态在kernel源代码里定义

 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)

R状态并不一定正在运行,而是正在运行和处于运行队列中的一种

int main()
{
  while(1);
  return 0;
}

S 睡眠状态(sleeping)

S 意味着进程在等待运行完成

(这里的睡眠有时也可叫做可中断睡眠 interruptible sleep)

下面展示两种S状态的进程

int main()
{
  sleep(50);
  return 0;
}

直接使用sleep()系列的函数直接使进程休眠

int main()
{
  int n;
  printf("Enter the num: ");
  scanf("%d",&n);
  return 0;
}

像scanf()这种需要等待外设(键盘)的接口,在阻塞等待资源的过程中会使进程进入S状态

D 磁盘休眠状态(Disk sleep)

有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。

T 停止状态(stopped)

可以通过(kill等命令)发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。

int main()
{
  while(1) sleep(1);
  return 0;
}

运行前先复制ssh渠道,其中一个窗口用于执行进程

make clean
make
./mycmd

另一个进程用于输入命令

先查看该进程的PID

ps ajx | head -1 && ps ajx | grep mycmd | grep -v grep

如图,这次的PID是20275

然后用kill发送SIGSTOP,对应参数为-19

kill -19 20275
ps ajx | head -1 && ps ajx | grep mycmd | grep -v grep

可以看到它已经由S状态改为T状态了

接下来发送SIGCONT,对应参数-18,使进程恢复

kill -18 20275
ps ajx | head -1 && ps ajx | grep mycmd | grep -v grep

可以看到已经由T变为原本的S状态了

X 死亡状态(dead)

这个状态只是一个返回状态,你不会在任务列表里看到这个状态。

Z 僵尸进程(zombie)

这个详细讨论下

产生

当该进程退出后,父进程尚未使用wait()之类的接口获取该进程的退出码,且父进程没有结束时,该进程会变成僵尸进程

父进程比子进程先退出时,子进程的父进程会改变为PID为1的进程,由新进程托管

下面创建一个例子

int main()
{
  pid_t id = fork();
  if(id == 0)//子进程
  {
    printf("child exit\n");
  }
  else//父进程
  {
    sleep(30);
    printf("father exit\n");
  }
  return 0;
}

运行程序后的30秒内查看进程状态,可以看到子进程进入了Z状态

行为

僵尸进程会以终止状态保持在进程表中,等待父进程读取退出状态代码

危害

  • 父进程一直未获取子进程的退出码,僵尸状态就会一直保持
  • 保持Z状态的进程的PCB仍然要一直维护,占用资源
  • 未退出Z状态的子进程可能造成内存泄漏

孤儿进程

当父进程比子进程先退出后,这个子进程便成了孤儿进程

既然原本的父进程没了,谁来托管子进程呢?答案是PID为1的那个进程

例子如下

int main()
{
  pid_t id = fork();
  if(id == 0)//子进程
  {
    sleep(30);
    printf("child exit\n");
  }
  else//父进程
  {
    sleep(1);
    printf("father exit\n");
  }
  return 0;
}

进程优先级

基础概念

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

查看优先级

首先写一个常驻进程

int main()
{
  while(1)sleep(1);
  return 0;
}

然后使用ps -la查看进程信息

./mycmd
ps -la

其中的PRI和NI与进程优先级有关,PRI就是进程的优先级,跟排队摇号一样,此值越小,被执行的优先级越高,而NI就是nice值,用于修正原PRI值

PRI值的计算

首先在看到的PRI值之外,还有个隐藏的基准值,本文用PRI0指代,这个PRI0是固定的,当NI值为0时,PRI == PRI0,而
无论怎么修改多少次NI,PRI的值减去NI值都相等,所以大可以推断在本系统(Linux)中,PRI值有如下计算公式

PRI = PRI0 + NI

修改NI值

因为修改NI值要管理员权限,所以要么root用户用top,要么信任用户用sudo top打开界面,然后按r,输入待修改进程的PID,按下回车后再输入新的NI值(有效范围-20~19)

此处可以用ps -la查看进程的PID,或调用getpid()

再写一个例子

int main()
{
  while(1)
  {
    printf("mypid: %d\n",getpid());
    sleep(1);
  }
  return 0;
}

sudo top然后按r

ps -la可以看到被修改后的进程优先级

其它概念

  • 竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级
  • 独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰
  • 并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行
  • 并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发

下一章环境变量

在Windows10上安装WSL2 WSL2是微软提供的Windows子系统,允许在Windows 10和11上运行Linux环境,提供更好的性能和兼容性。安装WSL2需要启用WSL功能、更新系统、安装WSL2内核,并设置为默认版本。之后,可以通过Microsoft Store安装Linux发行版,并使用WSL命令启动和管理它们。 阅读详情

相关推荐

利用Matlab绘制非线性系统相图:从理论到实践

本文详细介绍了如何利用Matlab进行非线性系统的相图绘制与相平面分析。从理论基础的状态空间转换出发,通过无阻尼线性谐振子和范德波尔振荡器等实例,手把手演示了使用ode45求解器绘制相图、分析平衡点与极限环的完整流程,并分享了方向场绘制、参数分岔探索及常见错误解决方案等高级技巧,为动力学系统分析与控制设计提供了直观强大的可视化工具。

yhn456789的博客 905

初识Linux下进程

我们在电脑上点开的一个个应用,其实就是一个个进程,进程仅仅如此吗?今天我们就来认识一下进程,那么话不多说,开启我们今天的话题!

欢迎来到阿熊的blog~~ 5158

【FPGA的基础快速入门23--------OV5640摄像头VGA显示】

FPGA的基础学习--------OV5640摄像头VGA显示OV5640简介二级目录三级目录 OV5640简介 OV5640同OV7725一样,都是Omni Vision(豪威科技)公司生产的CMOS图像传感器。 OV5640支持更高的分辨率(500W像素)、采集速率,具有更高的图像处理性能,主要应用在手机、数码相机、电脑多媒体等领域。 OV5640支持LED补光、MIPI(移动产业处理器接口)输出接口和DVP(数字视频并行)输出接口选择、ISP(图像信号处理)以及AFC (自动聚焦控制)等功能。 OV

暮雨中的坚果的博客 7689

Linux进程初识

进程是计算机中的重要概念,一个程序被操作系统加载进入内存那么这个程序就成为进程,一个程序可以启动多次产生多个进程,操作系统也要管理这些进程,本节将介绍关于进程的一些基本知识!我们普通用户无法直接与计算机中的硬件打交道,也就是说在没有操作系统的情况下,我们几乎是无法使用计算机的,于是计算机大佬们创造了各种各样的操作系统!Windows操作系统Linux操作系统Mac操作系统(基于Unix)Android操作系统(基于Linux)…等。

ARMCSKGT的博客 5434

基于 WebGoat 平台的 SQL 注入攻击

基于 WebGoat 平台的 SQL 注入攻击

Labulongdong的博客 3522

【AI Agent】Harness Engineering实践

Harness(运行宿主)是围绕 LLM构建的一套确定性工程系统,其核心职责是:承认模型的固有局限,用可控的工程手段逐一弥补,使"强大但不可靠的推理引擎"变成"可信赖的生产级Agent"模型 是发动机——提供原始动力Agent 是驾驶员——做出决策Harness 是道路、地图、护栏、仪表盘、维修站和质检线——确保行驶安全有序没有Harness,模型越强,可能只是更快地制造混乱。

sysu_lluozh 192

初识Linux · 进程替换

由前面的章节学习,我们已经了解了进程状态,进程终止以及进程等待,今天,我们学习进程替换。进程替换我们从如下几个点开始介绍,第一,直接看现象,第二,解释原理,第三,将代码改成多线程版本,第四,使用所有的替换函数,认识参数的含义。废话不多说,直接进入主题。

更新各种计算机技能~ 2890

落地实战!Python构建地方政府公开数据爬虫:政策/数据/规划全维度抓取(附反爬适配+数据清洗)

政务公开数据爬虫的核心不是“技术多先进”,而是“适配政务网站的特性”——慢一点、稳一点、合规一点,比追求抓取速度更重要。多地市爬虫集群:通过配置文件管理不同地市的URL规则,实现全省/全国政务数据抓取;图片表格识别:结合OCR工具(如pytesseract)识别政务网站的图片表格,转换为结构化数据;数据可视化:将抓取的统计数据导入PowerBI/Matplotlib,实现区域发展趋势分析。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1799

linux初识进程

计算机中的存储系统按照距离 CPU 的远近、访问速度的快慢寄存器 → CPU 缓存 → 主存(内存) → 外部存储(硬盘)这种分层设计的目的是在性能、容量和成本之间取得平衡。程序必须从硬盘加载到内存中运行,是由 CPU 的执行模型、硬盘的性能限制以及操作系统对进程管理和安全隔离的需求共同决定的;加载到内存的过程,标志着程序从静态文件转变为可被调度和执行的进程。好呀,这个问题在操作系统导论或计算机基础课里非常经典,而且容易混 😊我用直观 + 对比的方式给你讲清楚。狭义操作系统。

qq_46333318的博客 610

电商数据采集实战——多平台价格监控、比价分析与智能告警系统

在电商竞争日益激烈的今天,价格监控与比价分析已成为品牌商、渠道商和消费者的核心需求。对于品牌商而言,需要监控各渠道售价是否低于指导价(破价监控);对于消费者而言,希望在最佳时机以最低价购入心仪商品;对于数据分析师而言,价格波动数据是洞察市场趋势的金矿。然而,电商数据采集面临三大核心挑战:本文将基于 Python + Scrapy + Playwright + Redis + ClickHouse 技术栈,构建一套完整的电商价格监控与比价系统。架构分层说明:电商平台的反爬手段层出不穷,采集系统必须具备多层次的

从事移动开发八年,csdn博客专家,阿里云特邀专家,华为云云享专家,高级网络信息安全工程师,大数据工程师(高级),python技术开发(高级),HarmonyOS 应用开发者高级认证,现在某学校任教。 136

CKS-CN考试之路----04

根据上面信息我们知道,这个pod运行在default命名空间下,pod名字为cpu-77cd5ddcbf-bvb8w。可以从/etc/falco/falco_rules.yaml中获得相关内容,大概在文件的460行左右.编辑/etc/falco/falco_rules.local.yaml。7c688a8bfd69即是我们想要获得的docker id。将行为不当 Pod 的 Deployment 缩放为零副本。根据我们刚才定义的rule生成报告。访问/dev/mem 的 Pod。那么如果考试记不住怎么办?

Q先生 602

【Linux】初识进程

进程的基本概念;PCB的基本概念,task_struct的介绍;Linux系统如何组织进程;如何查看几进程:/proc以及ps命令的使用介绍;进程如何获取自己的pid和父进程的pid;如何创建子进程

lzb_kkk的博客 1683

华为OD机试双机位C卷-统计差异值大于相似值二元组个数(C/C++/Py/Java/Js/Go)

华为OD机试(机考)双机位C卷 【统计差异值大于相似值二元组个数】,提供Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试 - 统计差异值大于相似值二元组个数

qq_45776114的博客 783

[Linux进程概念]PCB进程初识

进程是程序的一个执行实例,是操作系统对程序执行的基本单位进程是程序的一次执行过程进程是一个程序及其数据在处理机上顺序执行时所发生的活动进程是系统进行资源分配和调度的一个独立单位进程控制块(PCB)是操作系统为了管理和维护进程而设置的一个专门的数据结构。作用:PCB使一个在多道程序环境下不能独立运行的程序(含数据)成为一个能独立运行的基本单位,或与其他进程并发执行的进程。通过PCB,操作系统可以跟踪和控制每个进程的运行,并在需要时恢复进程的执行。

2301_80239034的博客 1241

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

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

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

【linux】初识进程

认识进程

柯礼的博客 707

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

初识Linux · 进程等待

通过上文的学习,我们了解了进程终止,知道终止是在干什么,终止的三种情况,以及有了退出码,错误码的概念,对于错误码,我们知道不同的人对于错误码有自己的一套体系,对于退出码,我们知道可以使用echo $?来查看,并且知道了如果终止进程。那么本文,我们来学习进程等待,我们从三个方面来看,进程等待是什么?为什么要等待?等待是在做什么?从以上几个方面,相信同学对于Linux中的进程等待有更深层次的理解。

更新各种计算机技能~ 2447

初识进程——Linux

proc 目录是 Linux 系统中的一个虚拟文件系统,提供了关于内核、运行的进程和系统硬件的信息。这个目录在运行时动态生成,不占用磁盘空间/proc/(pid)该目录提供了访问和操作pid进程信息的接口,此接口提供指定进程的各种详细信息,可方便地了解和控制进程的状态和行为。可以利用ls查看。

2201_75373858的博客 1356

【Linux】初识Linux进程

linux进程初学(何为进程?进程的状态)

lsir10110_的博客 817

Linux系统之美:进程初识

Bash进程是当用户登录到Linux系统并启动Bash Shell时创建的一个进程。它是用户与系统交互的主要界面,允许用户通过命令行输入命令来执行各种任务。

yue_2899799318的博客 1261

【Linux学习笔记】初识进程概念和进程PCB

哈喽,各位小伙伴大家好!上期我们讲了gdb和cgdb 今天我们讲的是初识冯诺依曼体系和进程PCB。话不多说,我们进入正题!向大厂冲锋!

大白的编程日记. 1386
上一篇: vim基础指令集
下一篇: =C++= sizeof关键字详解
supdriver
博客等级 码龄3年 192粉丝 40原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值