【Linux系统编程】进程状态

文章目录

  • 前言
  • 1. 准备工作
  • 2. 阻塞、挂起状态的了解
    • 2.1 阻塞
    • 2.2 挂起
  • 3. 看看Linux内核源代码怎么说
  • 4. R运行状态(running)
  • 5. S休眠状态(sleeping)
  • 6. D不可中断休眠状态
  • 7. T暂停状态(stopped)
  • 8. t 追踪暂停状态 (tracing stop)
  • 9. X死亡状态(dead)
  • 10. Z僵尸状态 (zombie)

前言

在前面的学习中,我们已经学习了进程的概念和基本创建,以及如何通过相关的系统调用创建进程和获取进程标识符。

那为了弄明白正在运行的进程是什么意思,我们需要了解进程的不同状态

1. 准备工作

先问大家一个问题:我们使用一个应用的时候,比如我们打开电脑上的爱奇艺看电影,那在看电影的过程中这个应用对应的进程是否是一直在不停的运行呢?

🆗,那其实呢它并不是一直在不停运行的。
我们来举个极端一点的场景:
假设现在这里只有一个CPU,但是我们同时打开了多个进程,比如QQ、微信、爱奇艺、网易云音乐等,然后浏览器还有一些下载任务。
在这里插入图片描述
那这么多的进程在操作系统内被CPU调度运行的时候呢其实并不是从一个进程运行开始,一直不停直到运行结束的,而是每个进程被CPU运行一会儿,操作系统都会把它从操作系统上拿下来,然后把另一个放上来运行,这样重复的快速交替运行的。
一般呢我们把它叫做基于进程切换的分时操作系统,即不同的进程快速切换交替运行,同一时间段内它们的代码都可以得以推进,使得用户感觉多个应用程序几乎同时在运行,因为我们的感官和CPU的运行速度差的是很大的。

所以进程在运行的时候是可以被操作系统管理和调度的:

那这样的话就涉及一个问题,就是在某个时刻操作系统凭什么调度这个进程,让这个进程在CPU上运行而不是其它的进程呢?

那这就取决于进程状态相关的概念。
那在正式学习进程状态之前,我们先来了解两个概念——阻塞和挂起。

2. 阻塞、挂起状态的了解

2.1 阻塞

那我们先来了解一下阻塞:

阻塞即进程因为正在等待某种条件就绪,而导致的一种不推进(不被调度)的状态。

这样说呢,大家可能不太理解:

比如现在有一个进程被创建了(我们打开一个应用或运行一个程序),但是一直没有被CPU执行,那大家想一下这种情况在我们用户层面看到的是一个什么情况呢?
再比如我们有时候在Windows上启动了好多个程序,就可能会出现“卡”的情况。
那这种情况呢其实就可能是进程太多了,操作系统调度不过来了,目前操作系统正在调度的,就正在运行,没有被调度的,就卡在那了。
所以呢,说成大白话,阻塞就是进程“卡住”了。

再比如呢:

我们下载一些东西的时候,如果出现了断网或者0KB了,那这个时候这个下载的进度条就也卡住了。当然这个卡跟我们上面说的有的不一样。
但是这种情况其实也可以认为是阻塞状态。
所以,我们又得出:
阻塞一定是在等待某种资源

那如何理解这里的等待某种资源呢?

首先这里等待的资源可能是什么呢?
比如:磁盘、网卡、显卡各种外设等。
举个例子:
我们在下载某个东西的时候,突然断网了,那对应的进程就会被设置成阻塞状态了,CPU就不会再继续执行你了,你这个进程就要等到网络好了的时候才会被操作系统调度,被CPU继续执行。
就好比你去银行办理某个业务,办理之前你需要填一个单子,但是此时单子用完了,相应的工作人员去取了,然后你所在的这个柜台的工作人员对你说,那您先去旁边等一会吧,先让后面的人办理它们的业务,等您拿到单子填好之后再来办理您的业务吧。

那现实生活中的等待我们可能很好理解,那你就搬个凳子坐那里等一会呗,可是这里等待某种资源,它具体是如何等待呢?

首先,对于这些资源,操作系统肯定要管理起来,怎么管理的?
先描述,再组织!
这是我们之前讲过的。先搞一个结构体把它们的属性啥的都封装起来,然后在搞一个链表或其它高效的数据结构组织起来。
那进程呢?操作系统里面可能存在很多进程,那也要管理起来,如何管理?
先描述,再组织。
那就是一个task_struct的链表。
那某个进程在等待某种资源的时候呢其实就是把自己的task_struct放到对应资源的等待队列中。
在操作系统中,每个资源对应的描述数据结构通常会包含一个等待队列。这个等待队列用于存储等待该资源的进程或线程。
当一个进程请求某个资源时,如果资源当前不可用,操作系统会将该进程标记为阻塞状态,并将其对应的 PCB(task_struct) 移动到相应资源的等待队列后面。这样,CPU就可以调度其他可执行的进程来继续执行。

2.2 挂起

那下面我们再来了解一下挂起

还是通过一个例子给大家讲解:

假设现在有一个下载任务因为断网进入了阻塞状态
在这里插入图片描述
而此时呢操作系统的内存资源又特别紧张,那此时呢操作系统可能会做这样的事情,就是把这些阻塞状态的进程的代码和数据先交换到磁盘上,因为你这些阻塞的进程不被调度,但是你的代码和数据还放在内存里,那就太占用资源了。
然后等到这些阻塞的进程等待的资源就绪的时候,再把它们的代码和数据交换回内存,然后被CPU运行。
那其中操作系统把某些进程的代码和数据交换到磁盘上,此时就可以认为这些进程处在挂起状态
严格意义来讲,我们这里说的这种挂起状态全称可以叫做阻塞挂起状态,可以将挂起理解为一种特殊的阻塞状态

那为什么要先给大家说一下这两个概念呢?

因为这两个状态是操作系统中进程比较核心的两个状态,当然还有一个运行状态它相对比较好理解,我们后面针对具体的Linux操作系统去讲解。

当然如果我们去看一些操作系统的书籍或去网上搜进程的状态:

可能大部分都是这种
在这里插入图片描述
有的可能会有挂起状态。
而我们上面了解的内容其实就是基于操作系统这门课程来说的,可以认为它对于所有具体的操作系统都是成立的,可能比较抽象。

而我们下面呢,要针对一款具体的操作系统——Linux来学习一下进程的状态。

3. 看看Linux内核源代码怎么说

一个进程可以有多个状态(在Linux内核里,进程有时候也叫做任务),那首先我们可以来看一下在kernel源代码里关于进程状态的定义:

/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
* 翻译:任务/进程状态数组是一种奇特的"位图",用于表示睡眠的原因。
* 因此,"运行中"对应的位为零,你可以使用简单的位测试来检查
* 其他组合的状态。
*/
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 */
};

那这里的进程状态呢其实就是这几个

在这里插入图片描述
一共有7种
在这里插入图片描述
进程状态的变化其实就是该每个状态对应的那个数值就行了

接下来我们就来一一学习这几种状态

4. R运行状态(running)

R表示运行状态,那我问大家,如果一个进程是R状态,那么它一定是在CPU上运行吗?

那其实是不一定的!
也就是说,操作系统里可能有10个8个状态为R的进程,但是它们之中可能只有几个是正在CPU上运行的。
所以,其实操作系统维护调度进程也有相应的队列(运行队列
在这里插入图片描述
运行队列通常根据不同的调度策略进行管理,处在运行队列中的进程,它的状态就是R

所以总结一下:

R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里

那下面我们来写一个代码观察观察:

在这里插入图片描述
这样一个代码

再写一个Makefile:

在这里插入图片描述

然后我们来make生成可执行程序并执行一下:

在这里插入图片描述
大家看,现在这个进程在运行吗?
当然,我们肉眼可见它在不停的运行。
那我们来查看一下,前面学过查看进程的命令
在这里插入图片描述
我们看到查出来的进程的状态是s,后面那个+号我们先不管,那s对应的状态是啥呢?
s呢其实是休眠状态,后面我们就会学。

那这里怎么回事啊?

为什么我们查到的状态是s休眠呢,虽然s状态我们还不太了解,但我知道它不是R运行状态,那这是怎么回事呢?

🆗,至于原因呢先不急,我呢现在把我们上面的代码修改一下:

在这里插入图片描述
我把这句代码注释掉。
然后我们重写make并运行
在这里插入图片描述
这次再查看
在这里插入图片描述
大家看这次就是R运行状态了

那这是怎么回事呢?

🆗,我们第一次的代码,是不是一个死循环然后里面一个打印语句,所以它允许的时候是不是要不断的频繁访问显示器这个外设啊?
但是,我们每次访问显示器的时候,他一定是就绪的吗?
如果不是就绪的话,那我们的进程是不是就不在进程的运行队列里面排队了,而是在显示器这个外设资源的等待队列里面排队。
所以,我们才查到了S状态,它也是阻塞状态的一种。
所以这个进程并不是一直在CPU的运行队列里面的,而是在运行队列和外设资源的等待队列里面不断切换的。

那为什么我们查到的是S状态而不是R状态呢?

我们这里只有一行代码,CPU执行的时候是很快的,而等待外设的过程相对于CPU执行代码的速度是非常慢的。
所以我们ps命令查的时候会发现查到的差不多都是s状态,可能查1万次能有一两次是R状态。

那为什么我们后面把打印注释掉查看到的就是R状态了:

那也很好解释,因为我们把它注释掉,程序里面就没有访问资源的代码。
只有while循环判断,while循环判断就是纯计算,所以它不需要访问外设,那只要被调度,就一直处在运行队列里,所以我们查到它的状态总是R状态。

那下面我们就来学习下一个状态——S状态

5. S休眠状态(sleeping)

概念大家可以先看一下:

S休眠状态(sleeping): 意味着进程在等待事件完成(这里的休眠有时候也叫做可中断修眠(interruptible sleep))。

那首先呢,可以告诉大家,S状态就是一种阻塞状态

我们再来修改一下代码:

在这里插入图片描述
改成这样

我们来运行一下:

在这里插入图片描述
其实就是一个死循环嘛,我们输入一个数,他就给我们打印一个数

那我们来查一下这个进程的状态

在这里插入图片描述
我们看到此时它的状态就是S。
因为它此时正在等待资源啊
在这里插入图片描述
等待我们通过键盘输入数据。
所以它此时就不在CPU的运行队列里,没有被调度,而是在键盘资源的等待队列,那就是我们上面说的阻塞状态。
而我们说了,S休眠状态其实就是阻塞的一种,而且S这种休眠状态被称为可中断休眠
在这里插入图片描述
我们CTRL+c就可以终止该进程

那现在大家再回过头来看S状态的概念:

S休眠状态(sleeping): 意味着进程在等待事件完成(这里的休眠有时候也叫做可中断修眠(interruptible sleep))。

就应该比较好理解了

那我们继续

6. D不可中断休眠状态

D 磁盘休眠状态(Disk sleep)也叫不可中断休眠状态(uninterruptible sleep),在这个状态的进程通常要等待IO的结束。
也算是一种阻塞状态。

那么D 状态呢?

其实我们平时大概率是遇不到的,一般是那些做系统管理的,运维的等等这些人员可能遇到的会比较多。

那该如何理解这个D 状态呢?我们来看这样一个场景:

在这里插入图片描述
假设现在呢这个进程想往磁盘上写100MB的数据。
那它就告诉磁盘,我想往你身上写100MB的数据;然后磁盘说,那我的速度比较慢,你要等等我;那此时进程就被设置成了阻塞状态,就去磁盘的等待队列里面排队了。
那CPU呢就对这个进程说,那你先写数据吧,我先运行其它的进程,等你资源准备就绪了,我再调度你。
此时,操作系统路过。
作为系统的管理者,它发现此时系统的内存资源已经非常紧张了,如果再有进程就要挂了,但是此时操作系统却发现你这个进程却不在运行队列里,而是啥也不干在这里等。
那操作系统就想,那我把你杀掉吧,于是,这个进程就被干掉了

与此同时呢,又发生了新的状况,这个进程被干掉了,此时磁盘还在写数据,但是,由于某些原因,数据写失败了。
那然后呢磁盘就要给这个进程说,你的这些数据写入失败了,但是此时却发现人不见了,找不到这个进程了。我还想着告诉你,然后让你反馈给用户呢!
那现在进程被杀死了,就只剩磁盘拿着这100mb的数据,不知该怎么处理了。
可以直接把这些数据丢掉嘛,如果这些数据很重要呢!

那此时这种情况该如何处理呢?

上面的故事呢,涉及3个比较关键的角色——操作系统、进程、磁盘。
那么请问:导致上面那样的情况出现,是谁的锅呢?
那我们分析一下它们做的好像都是合理的。
那怎么办呢?如何避免这种情况的出现呢?
那其实只要我们保证这个进程不能被杀死就行了啊。

所以呢,就有了这样一种休眠状态:

即D状态——不可中断休眠状态。
如果一个进程处在这种状态,它就无法被杀死,操作系统也不行。
所以如果出现D状态的话,那你的机器可能就快要宕机了,因为此时磁盘的压力可能已经非常大了,严重变慢,才导致出现这种情况。
所以我们才说这种状态我们大概率遇不到。

7. T暂停状态(stopped)

T暂停状态呢其实也是一种阻塞状态:

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

我们再来修改一下代码:

在这里插入图片描述
我们make并运行一下
在这里插入图片描述
当然现在如果我们查他的状态是S
在这里插入图片描述

那我们怎么让它暂停呢?

再来学习一个新命令
在这里插入图片描述
还是kill命令,后面我们还会详细讲,现在先用。
然后呢-19这个选项,加上对应进程的PID,他就可以暂停一个进程。

我们来试一下:

在这里插入图片描述
目前它的状态是S
在这里插入图片描述
我们看到执行之后这个进程就停止了,而且我们再去查看进程状态就变成T暂停状态了。

那我想让他继续运行呢?

再学一个命令
在这里插入图片描述
kill -18 就可以让指定的进程继续执行
在这里插入图片描述
我们看到执行之后它就重新运行起来了
此时再去查看进程状态
在这里插入图片描述
就又变回S了。

但是呢!

在这里插入图片描述
此时我们去CTRL+c无法终止这个进程了。
那除此之外不知道大家有没有注意到一个现象
前面我们查看的状态字母后面还有一个“+”加号,但是自从上面变成T状态之后,就没有+了

那进程状态后面的+表示什么呢?

🆗,如果带+的话,表明该进程是在前台运行的,CTRL+c可以终止掉它;
如果没有+,就表明这个进程变成了在后台运行,后台运行的时候我们可以去正常执行我们的shell指令
在这里插入图片描述
但是它在后台还会一直运行,且CTRL+c终止不了
那有办法杀掉它吗,再来认识一个命令
在这里插入图片描述
kill -9
在这里插入图片描述
就可以杀掉这个后台进程(当然前台的也可以)

8. t 追踪暂停状态 (tracing stop)

然后我们看到,除了T之外:

在这里插入图片描述
还有一个t——追踪暂停状态

那其实我们GDB调式程序的是时候,如果打了断点,程序在断点处停下来,此时程序就会停止执行进入t状态

我们来演示一下:

那首先Makefile里面我们要加一个-g选项让它以debug版本生成,这是我们之前讲过的内容
在这里插入图片描述
然后我们GBD调式一下
在这里插入图片描述
查看一下代码
在这里插入图片描述
那我现在在第12行打个断点
在这里插入图片描述
然后我们r开始调式
在这里插入图片描述
它就在12行停下来了

那此时我们去查看它的状态

在这里插入图片描述
就能看到对应进程的状态就变成t了
如果我们退出gdb
在这里插入图片描述
在这里插入图片描述
此时再查就没有了

那这就是追踪暂停状态

9. X死亡状态(dead)

X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态。

它是一个瞬时状态,我们也很难查到,不过与之相关的,还有一个重点状态——Z (zombie):僵尸状态

那这两个我们放到一块讲

10. Z僵尸状态 (zombie)

首先问大家一个问题,我们为什么要去创建进程?

那其实就是为了让进程帮我们办事嘛,完成某个任务。
那对于进程执行的结果,我们有时候可能是关心的,有时候可能并不关心。

那我们来讲一个东西:

我们平时写的C/C++ 代码,main函数里面最后一般都要有一个返回值return 0;
那大家可能不是特别清楚为什么main函数要有一个返回值,这个返回值是做什么的呢?
🆗,那这个返回值呢其实叫做进程退出码
另外呢我们直接有讲过:
任何命令行上启动的进程,都是bash的子进程,所以我们运行一个程序的时候,可以认为是父进程bash创建了一个子进程,让这个子进程去帮忙办事。
那你事办的怎么样,结果如何?父进程是怎么知道的呢?
它是通过退出码来获悉的。
在这里插入图片描述
在这里插入图片描述
那如何获取一个进程的退出码呢?
echo &?
在这里插入图片描述
就可以获取进程的退出码

不过呢:

我们上面的代码没什么意义,如果我们关心进程的执行结果,比如有一个算法,判断它执行的结果对不对。
我们改一下代码
在这里插入图片描述
假设正确结果是0,如果算法返回值等于0,就返回0,否则,返回3代表返回结果不正确。
那我们再来运行查看一下退出码
在这里插入图片描述
是0,表示结果正确
如果运算结果不对
在这里插入图片描述
那么
在这里插入图片描述
退出码就变成了3

那关于上面讲的这个退出码,大家先了解一下,后面还会说。

那再回到我们上面讲的:

我们创建进程帮我们做事有时候是关心结果的,那如何获取这个结果呢?
其中一个方式就是通过退出码

那么:如果一个进程退出了立即变成了X死亡状态,那父进程bash有没有机会拿到这个退出结果呢?

所以,为了方便子进程退出后父进程或操作系统获取该进程的退出结果,Linux进程退出时,进程一般不会立即死亡,而是要维持一个Z状态即——僵尸状态。
等这个进程真正被回收了,它的状态就会变成X死亡状态。(如何回收我们后面会讲)

那处在僵尸状态的进程就叫做僵尸进程,关于僵尸进程的进一步理解我们下篇文章讲解…
在这里插入图片描述

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

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

相关文章

设计模式6、适配器模式 Adapter

解释说明:将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作 目标接口(Target):当前系统所期待的接口,它可以是抽象类或接口 适配者(Adaptee)&#xff1a…

C#(CSharp)入门实践项目(简易回合制游戏)

项目名称 木木夕营救公主 项目介绍 这是一个小游戏,你将扮演一个英雄(木木夕),去打败恶龙,拯救出公主,该项目采用回合制战斗模式,由于角色的血量和攻击为随机数,所以需要靠运气才…

Spring | 基于SpringBoot的多数据源实战 - 使用seata实现多数据源的全局事务管理

Spring | 基于SpringBoot的多数据源实战 - 使用seata实现多数据源的全局事务管理 引言1.1 多数据源的必要性1.2 多数据源的应用场景 实战演示2.1 创建实体类2.2 配置数据源2.3 实现数据源配置类2.4 配置Repository类2.5 运行与验证 事务管理与数据一致性3.1 事务管理3.2 使用Se…

变电站无人值守方案:提升效率与增强安全性

随着信息技术、人工智能、大数据的发展进步,电力行业正逐步向智能化转型。其中,无人值守变电站成为了现代电力系统的明显趋势。这种新型的运营模式不仅提高了效率,还极大地增强了电力系统的安全性。 无人值守变电站的核心概念是在没有人类现场…

Adams齿轮副

1.运动副 添加旋转副的时候,必须先物体后公共part(即此处的ground),最后再选择质心点 2.啮合点 啮合点marker的z轴必须是齿轮分度圆的切线方向 3.啮合点 两齿轮的旋转副,和啮合点,即cv marker ,必须属…

win10打开VMware 16 pro里面的虚拟机就蓝屏怎么办

2023年9月30日,周六下午 今天下午我也遇到了这个问题,后来解决了,于是记录一下我的解决办法 目录 1、打开控制面板,并选择“程序和功能” 2、点击“启动或关闭Windows服务” 3、勾选两个服务 4、重启电脑,大功告成…

【CMU15-445 Part-14】Query Planning Optimization I

Part14-Query Planning & Optimization I SQL is Declarative,只告诉想要什么而不需要说怎么做。 IBM System R是第一个实现query optimizer查询优化器的系统 Heuristics / Rules 条件触发 静态规则,重写query来remove 低效或者愚蠢的东西&#xf…

牛客 ( 计算几何

#include <bits/stdc.h> using namespace std; using ll long long; using PII pair<double , double>; int n; PII p[3000010]; vector<PII> pp; PII yuan(PII a , PII b , PII c) {//已知三个点确定圆的半径和圆心double x1 a.first,x2 b.first,x3 c.…

华为云云耀云服务器L实例评测 | 实例评测使用之体验评测:华为云云耀云服务器管理、控制、访问评测

华为云云耀云服务器L实例评测 &#xff5c; 实例评测使用之体验评测&#xff1a;华为云云耀云服务器管理、控制、访问评测 介绍华为云云耀云服务器 华为云云耀云服务器 &#xff08;目前已经全新升级为 华为云云耀云服务器L实例&#xff09; 华为云云耀云服务器是什么华为云云耀…

协议-TCP协议-基础概念02-TCP握手被拒绝-内核参数-指数退避原则-TCP窗口-TCP重传

协议-TCP协议-基础概念02-TCP握手被拒绝-TCP窗口 参考来源&#xff1a; 《极客专栏-网络排查案例课》 TCP连接都是TCP协议沟通的吗&#xff1f; 不是 如果服务端不想接受这次握手&#xff0c;它会怎么做呢&#xff1f; 内核参数中与TCP重试有关的参数(两个) -net.ipv4.tc…

asp.net企业生产管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

一、源码特点 asp.net 企业生产管理系统 是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库为sqlserver2008&#xff0c;使用c#语 言开发 二、功能介绍 (1)用户管理&…

索尼 toio™应用创意开发征文|检测工业平台震动

虽然索尼toio Q宝机器人主要是为儿童教育娱乐开发的&#xff0c;但我认为它在工业等领域也有一定应用潜力。例如&#xff0c;工业领域经常会有某些平面在实际作业中持续震动&#xff0c;导致零件过疲劳、平台失去稳定等问题。而这样的平台往往位于机器内部&#xff0c;从外部很…

TensorFlow学习1:使用官方模型进行图片分类

前言 人工智能以后会越来越发达&#xff0c;趁着现在简单学习一下。机器学习框架有很多&#xff0c;这里觉得学习谷歌的 TensorFlow&#xff0c;谷歌的技术还是很有保证的&#xff0c;另外TensorFlow 的中文文档真的很友好。 文档&#xff1a; https://tensorflow.google.cn/…

云安全【阿里云ECS攻防】

关于VPC的概念还请看&#xff1a;记录一下弹性计算云服务的一些词汇概念 - 火线 Zone-安全攻防社区 一、初始化访问 1、元数据 1.1、SSRF导致读取元数据 如果管理员给ECS配置了RAM角色&#xff0c;那么就可以获得临时凭证 如果配置RAM角色 在获取ram临时凭证的时候&#xff…

ubuntu安装PhotoPrism,并开启安卓照片同步

之前安装了黑群晖7.2&#xff0c;并开启了Photo&#xff0c;照片同步用的挺好。唯一的缺陷是群晖的照片搜索太弱鸡了&#xff0c;基本上关键字搜索是一点不可用&#xff0c;常见的“花”&#xff0c;“山”&#xff0c;“文件”&#xff0c;“证件”都是不可用的。 后来了解到了…

Ubuntu基于Docker快速配置GDAL的Python、C++环境

本文介绍在Linux的Ubuntu操作系统中&#xff0c;基于Docker快速配置Python、C等不同编程语言均可用的地理数据处理库GDAL的方法。 首先&#xff0c;我们访问GDAL库的Docker镜像官方网站&#xff08;https://github.com/OSGeo/gdal/tree/master/docker&#xff09;。其中&#x…

DAMA-DMBOK2重点知识整理CDGA/CDGP——第14章 大数据与数据科学

目录 一、分值分布 二、重点知识梳理 1、引言 1.1 业务驱动因素 1.2 原则 1.3 基本理念 2、活动 2.1 定义大数据战略和业务需求 2.2 选择数据源 2.3 获得和接收数据源 2.4 制定数据假设和方法 2.5 集成和调整数据进行分析 2.6 使用模型探索数据 2.7 部署和监控 …

Android 遍历界面所有的View

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业变现、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、实践四、 推荐阅读 一、导读 我们…

FFmpeg 命令:从入门到精通 | ffmpeg 命令分类查询

FFmpeg 命令&#xff1a;从入门到精通 | ffmpeg 命令分类查询 FFmpeg 命令&#xff1a;从入门到精通 | ffmpeg 命令分类查询ffmpeg -versionffmpeg -buildconfffmpeg -formatsffmpeg -muxersffmpeg -demuxersffmpeg -codecsffmpeg -decodersffmpeg -encodersffmpeg -bsfsffmpeg…

【QT】使用toBase64方法将.txt文件的明文变为非明文(类似加密)

目录 0.环境 1.背景 2.详细代码 2.1 .h主要代码 2.2 .cpp主要代码&#xff0c;主要实现上述的四个方法 0.环境 windows 11 64位 Qt Creator 4.13.1 1.背景 项目需求&#xff1a;我们项目中有配置文件&#xff08;类似.txt&#xff0c;但不是这个格式&#xff0c;本文以…