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

【linux】:进程状态(僵尸进程等)以及环境变量

 

 

文章目录

  • 前言
  • 一.进程状态
  •     进程的优先级
  • 二.环境变量
  • 总结

 


前言

  本篇文章是接着上一篇【linux】:进程概念的后续,对于有基础的同学可以直接看这篇文章,对于初学者来说强烈建议大家从上一篇的概念开始看起,上一篇主要解释了冯诺依曼体系以及操作系统的概念还有在linux系统中进程是什么样的,如何去查看一个进程,如何给一个进程多开一个子进程以及为什么fork()函数可以有两个返回值的问题。


 

一、进程状态

为了能更深刻的理解linux中的进程状态,我们把linux中的内核源代码拿出来看一下:

/*
* 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 */
};

task_struct是一个结构体,内部会包含各种属性,其中就包括状态,如下图:

3df939f7365247b194331616c0242f2d.png

我们先来讲解阻塞和挂起这两个重要的概念,阻塞就是进程因为等待某种资源就绪,而导致的一种不推进的状态。我们经常可以看到不管是手机还是电脑当打开的软件很多的时候,就有出现应用卡顿的情况,这是因为当我们打开很多的软件的时候进程也变多了,操作系统调度不过来了,这个时候卡的那个进程就是阻塞了。再比如说我们下载一个软件,下载了一半没网了,这个时候下载进度就不动了,这个时候这个进程就变成了阻塞状态,只有当网络好了能继续下载了CPU才会继续调度这个进程,所以这个进程卡住了是在等待某种资源就绪,当资源就绪了就会被CPU调度取消阻塞状态。所以进程要通过等待的方式,等具体的资源被别人用完之后,再被自己使用。那么进程等待某种资源就绪的过程中,资源指什么呢?这里的资源指软硬件资源,比如:磁盘,显卡,网卡等各种外设。下面我们用图解释一下阻塞的过程:

2ae1295df6334863ada20d33b28ce3c7.png

我们前面讲过操作系统对于软硬件的管理是先描述在组织,所以对于网卡磁盘等也是通过struct来描述的,当CPU正在跑一个进程的时候,这个进程突然没网了这个时候就将这个进程先变成阻塞状态,然后看下图:

d567697866df45b392b8e42d1f11d9b0.png 这个时候因为网络的问题进程需要等待网络恢复才能继续在CPU上运行所以这个进程就会链接在网卡的尾部等待网卡资源就绪也就是网络恢复才可以正常运行。所以PCB是可以被维护在不同的队列中的。

阻塞:阻塞就是不被CPU调度。一定是因为当前进程需要等待某种资源就绪。一定是进程task_struct结构体需要在某种被OS管理的资源下排队。

下面我们解释一下挂起的概念:

e502b206bc824aa1b851ed5293bc2b46.png

 上图是一个进程正在被CPU调度,然后突然没网了,看下图:

afbc5920d8074e9e8bba28255f603dfd.png

这个时候进程进入阻塞状态等待网卡设备就绪,由于内存中空间有限所以对于阻塞状态的进程的代码和数据来说无疑是浪费空间的,所以操作系统会先将阻塞状态的进程的代码和数据放入磁盘中,将内存中的代码和数据释放掉。

c8392f05a4c54287895a92073efe7a74.png

等过了一段时间,网卡设备就绪了,这个时候进程会继续被CPU调度,在这之前需要把磁盘中的代码和数据继续放入内存中

ca9e009b6ca941d9a5e38b34d4984b32.png 以上的将代码和数据先放入磁盘等待网卡设备就绪然后就绪后再将磁盘中的代码和数据放入内存的过程就叫做挂起。

在这里问一个问题,进程是R状态一定是在CPU上运行吗?答案是不一定。进程一般是什么状态,要看这个进程在哪里排队,看下图:

d4a02721d55540829586b381cb1827ce.png

首先我们创建一个.c文件然后写一个死循环代码,然后创建Makefile文件:

d22d81fc78f746f289140395fbc4ba63.png 接下来我们直接运行并且查看当前进程状态:

14dacd07de7f4873844a786d735f697f.png

e7bad5ae41884d2c943545a068d362a3.png 我们先用ps axj | head -n1指令调出进程属性,然后后面加上grep mytest过滤出mytest可执行程序的进程,后面加的grep -v grep是过滤掉grep自己本身的进程,最后成功的显示出这个进程,我们可以很清楚的看到这个正在运行的程序的状态并不是R而是S+,S代表休眠状态,接下来我们将打印注释掉试一下是什么状态:

7e4da7b97e9741e9b23e5b024d3d5d8f.png

77d11feecf4248a8b7ded3609caa15eb.png

7507eb2bd25146bd9f8a6cf3afb38c22.png 我们可以看到当将打印代码注释掉后这个进程的状态变成了R,这个时候为什么是运行状态了呢?因为printf打印需要打印到屏幕上,而屏幕就是一种外设,频繁的往屏幕打印进程会等待屏幕就绪才可以打印,而CPU的运算非常快外设的速度却很慢,所以CPU早就跑完了代码接下来将进程状态设为阻塞状态让这个进程去屏幕后面等待屏幕就绪当屏幕就绪后又会重新被CPU调度然后执行重复的操作。

所以进程是R状态不代表进程在运行,而代表该进程在运行队列中排队。

S状态是休眠状态,可中断休眠。而S状态就是一种阻塞状态。

接下里我们演示一下,首先修改一下代码:

bcbf6fd0ae7f44d08a9efadd4d41cd52.png

2a353a55f92b451490226f37241198b6.png 这个时候我们去看进程状态。

53c6773db78c48dda6a94a5dff508eac.png

为什么是S状态呢?因为进程会等待键盘资源就绪,也就是说只有键盘输入了才叫键盘资源就绪这个时候才会被CPU调度 

e040603ad4e146abb89fe3f4b56abd9d.png

e4acf87bd34842b18a9d48f3d10a3032.png 当我们终止程序后程序就结束了这个进程也结束了,对应了S状态是可中断休眠状态。

D状态也是一种休眠状态,D状态是不可休眠状态。D状态在生活中我们基本不会遇到,就是磁盘基本快满了还在往磁盘存数据,这个时候你就会发现你的电脑非常卡而且不能强制进行任何关闭操作,如果关电源会导致资料丢失所以不可中断只能等磁盘自己恢复。

T状态叫暂停状态,下面我们来演示一下T状态:

a544bbb1cb7e402583c5563d5c66b6d0.png

 我们先讲代码修改一下方便演示:

aa147b94433c422aa89cd103c6eff458.png

6978af082c6f491c8a572a9a736eb61a.png

 运行后我们可以看到这个时候的进程状态为S,这个时候我们使用一个暂停命令:

f25550a2b0ba4f72958ba82284e6faac.png

19号这个命令sigstop为暂停然后我们使用一下:

b6c9f9041b664231bfd65d69319b2099.png8d582a80ebc44450820d3447ad60d2b6.png

2f4d65e576a543cfb805521e5cb46fb7.png 这个时候我们能很清楚的看到进程变为T状态了并且程序确实暂停了,这个时候我们如何恢复运行呢?

f67fd315f1e940098782d7b7107add68.png

这里的18号代码为sigle continue的简写就是继续的意思

995f09920c694de6a1d03fa8ea89f1a2.png 0ac9404a84c5437384add93dee997e03.png

这个时候程序就又可以继续了。但是我们发现这个时候我们用ctrl+c关不掉了,并且进程状态也变了。

83ab6e9f914b498699b2c148de238f9a.png

4903185d9d2c494f9a7b72f2b33a5a7a.png 从原来的S+变成了S为什么就不能终止程序了呢,因为状态后面带+号是代表程序在前台运行,在前台运行的程序可以ctrl + c结束,没有+就变成了在后台运行,这个时候我们只能通过kill命令杀掉这个进程。

ed0135960216496ca661c0b3d6c8d7c9.png

6f502a7fc2cf458090e5ca1eb76d661f.png 7a01e949aa5b43598fd0643605c7b9c8.png

23f291c5a7784085bf1c5304d6f8b663.png 这个时候程序就结束了,不管是前台或后台我们都可以用kill杀掉。

X状态被称为死亡状态,Z状态称为僵尸状态,下面我们解释一下这两个状态:

为什么我们要创建进程呢?因为我们需要进程为我们做事,我们写过C语言代码,知道每个main函数没必须返回0,这是因为我们要知道函数的结果,如果没有返回值我们就无法确定一个函数是否允许,所以我们需要进程的返回值来确定进程的状态。那么如果一个进程退出了立马变成X状态,作为这个进程的父进程,有没有机会拿到结果呢?linux当进程退出的时候,一般进程不会立即彻底退出,而是要维持一个状态叫Z,也叫作僵尸状态,方便后续父进程(OS)读取该子进程退出的退出结果。那么如何看到僵尸状态呢?子进程退出,但是不要回收子进程。下面我们演示一下:

8f42c19aafdc4a36b0bb591279f1ae2e.png

5ec9051a3b7b43ceb60ab8a4ce8c9e1c.png

893c404472b841888f799d563970654e.png 这个时候两个进程都处于S状态,根据我们刚刚所说的只要让子进程先退出就能看到僵尸状态。

59e025d4c1d44a36baddafcf0282dbae.png

370a95e14a794840b2d23bb85aa64cfa.png

03b920da86e44ef28d32b0df02ba37bf.png 我们可以清楚的看到,当我们将子进程杀掉后子进程的状态变成了Z也就是僵尸状态,在mytest后面的单词<defunct>这个单词就有死人的意思,那么僵尸状态在这会占用资源吗?答案是会的,维持僵尸状态会占用资源,僵尸状态必须释放,如果这样的僵尸状态很多那么机器就很容易卡死。而维护僵尸状态的意义就是让父进程能够读取子进程退出的信息。

僵尸状态的危害:

僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程(使用wait()系统调用没有读取到子进程退出的返回代码时就会产生僵死(尸)进程僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。 所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态
进程的退出状态必须被维持下去,因为他要告诉关心它的进程(父进程),你交给我的任务,我办的怎么样了。可父进程如果一直不读取,那子进程就一直处于Z状态。 维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话 说,Z状态一直不退出,PCB一直都要维护。那一个父进程创建了很多子进程,就是不回收,是不是就会造成内存资源的浪费?是的!因为数据结构对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空间! 内存泄漏?是的

刚刚我们看到子进程先退就变成僵尸了,下面我们看看父进程先退会怎么样。 

99fd9a5c77c549098a0bce7551ae7744.png

 我们将代码修改一下方便观察,下面我们用命令观察一下:

a96f149c0b7b40d890c2a156d719976b.png

 我们先用shell编程每隔1秒监测一下进程。然后将进程跑起来:

961767d5a92f49b0873bb469384b1a06.png f3034cf04323476eaa0907e833b9b05d.png

 我们可以看到一开始有两个进程,当父进程结束后只剩下了子进程,这个时候我们发现子进程的状态从S+变成S了,也就是说从前台变成后台了。

451607d1174940e0808b443b39a592a1.png4d68ca3353174cb7a3060059716b962b.png

 我们可以看到这个时候已经不能用ctrl+c终止程序了,只能用kill杀掉子进程。那么为什么父进程先退出的时候没有变成僵尸呢?这是因为这个先退出的父进程被他的父进程回收了,他的父进程就是bash。怎么证明呢?在上图中我们发现pid为15529的进程的父进程一开始为15528,当15528退出的时候,15529这个子进程又重新给自己找了个爹pid为1,pid为1的进程我们都知道,这就是操作系统,也就是说,父进程退出,子进程会被OS自动领养(通过让1号进程成为新的父进程),那么这个被领养的进程就被称为孤儿进程。那么为什么我们上面演示子进程退出的时候子进程变成僵尸状态了呢?因为上面我们为了演示出僵尸状态故意没有将代码写完,因为没有等待,所以子进程变成了僵尸状态。那么为什么子进程会被自动领养呢?因为如果不领养就导致没人能找到子进程,一旦子进程退出就没人回收这个进程了,那么这个子进程就是一种游离状态,这样就会造成资源浪费,也就是内存泄漏。

进程的优先级

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

优先级和权限有什么区别呢?答案是权限代表了能不能的问题,而优先级是你执行的先后顺序,优先级已经确定了你可以干某件事只是取决于先后问题。那么为什么会有优先级呢?因为CPU的资源有限。

我们可以用ps -l命令查看进程中的优先级,如下:

df1fffff63724d0bbbe2924ba3f2d4a4.png

在上面的图片中,PRI代表程序的优先级,NI代表进程优先级的修正数据。PRI的值越小进程的优先级越高,而NI值可以理解为是改变PRI的值从而修改进程的优先值。PRI(新) = PRI(旧)+NI

而在linux系统中,旧的PRI值一定为80。下面来演示一下:

79ffc6fdadad455d8c6fdeeb61458ee9.png 我们先随便写一个死循环程序,然后运行起来。

e4981ebd63204f0e895d8fea845a44b7.png

 可以看到程序已经跑起来了,这个时候用top命令去修改优先级。top进入后输入R,R就是renice的意思,然后输入pid

3d7fa8cbfb9e49199e4739b87de3e0be.png

8e8cdad160a24639bc449b07c165ec7b.png

 接下里让我们输入nice值,我们就调整为-20

f5df746543964949bd26d5abdafac521.png

 我们可以看到确实成功修改了这个时候我们再修改为100

155128a64bc24b899284c2a0d3f9c908.png

c92ae562786a4c9cba1bb673cfc4a9b6.png为什么是不是180呢?因为我们优先级的调整范围是-20到19这个级别,也就是说最小是-20,最大是19。 进程的优先级在我们平时使用中都不会调整,一般都会使用默认的优先级,大家知道该怎么修改就可以了。

二、环境变量

环境变量一般是指操作系统中用来指定操作系统运行环境的一些参数,比如我们在编写c/c++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找,环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性。比如我们在linux中写的可执行程序,要想这个程序先运行起来必须在前面就是 .   /   ,  . 是在当前路径,/ 是路径分隔符,而同样为可执行程序的 ls指令等却不需要在前面加上./,难道就因为一个是被纳入系统的程序一个是我们自己写的吗?其实并不是这样,系统的指令之所以不需要在前面加./是因为有环境变量的帮助,这个环境变量会帮我们去搜索系统中的ls命令,而这个环境变量叫PATH,下面我们查看一下这个环境变量:

eef2400857064d3984f83907a6e6973a.png

 echo是打印一个字符串,PATH是环境变量,前面加上$符号就是获取环境变量的内容,这里与指针解引用相似。

和环境变量相关的命令:

1.echo:显示某个环境变量值

2.export:设置一个新的环境变量

3.env:显示所有环境变量

4.unset:清除环境变量

5.set:显示本地定义的shell变量和环境变量

fa6597d954d5457a9cbf4f001828b532.png

 我们之前讲过linux的指令,which可以查看指令的路径,通过查看我们发现ls指令在usr/bin中,而PATH环境变量是根据冒号一个一个路径进行查找,当找到usr/bin这个路径的时候就不需要我们在使用的时候加./了。那么如何将我们写的可执行程序添加到环境变量中呢?看下图:

db99d84aed4d48f88c3223e9c1526bbf.png

 我们写了一个程序用来演示。接下来我们用命令将我们写的这个程序加入到环境变量中

9179e0db8aa74d2196d602781ee889d4.png

 可以看到我们成功添加,然后我们试试可以直接运行吗?

c3f9e490a15a4b9593cea23c8f8b8584.png我们看到是可以运行的并且不用在输入前面的./了

827ead7ebe764ca78c953512cf28bc88.png

 这个时候我们的其他指令不能使用该怎么办呢?这时只需要重新登录xshell即可。

那么我们怎么样才能既使用系统的指令又用自己的呢?

69c775a1039445efa5443b330d36f084.png

 我们将刚刚的命令修改一下就可以既使用系统的指令又用自己的。当然除了这一种方式我们还可以直接将要添加的可执行程序的目录拷贝到PATH中,而这种方式在linux中相当于软件的安装。

下面我们用env指令查看系统中的环境变量:

d4dbfd76edcf4344be89b8c9c2551257.png

 我们可以看到系统中的环境变量很多,当然我们也可以用history指令查看以往我们用过的指令:

10c64bfd8c7d49a7880dd3db7da4d4da.png

 为什么从10开始呢,因为history只会保留最新的1000条指令,一旦超过就会删掉原来旧的指令。

下面我们用C语言来获取系统中的环境变量:

1053a65ec3f145e0ac903e548dfecbb6.png

 我们再写c/c++的时候从来没有写过main函数的参数,而main函数实际上有3个参数,这三个参数不需要我们手动去写编译器会默认给我们传参,envp这个指针数组中每一个指针都指向一个有效的字符串,而最后一个指针必须以NULL结尾。

437592c9d81447f69511ffb70f3eb002.png

 然后我们将代码写完整如下图:

517d42ddc8ed4c258f8552a19429ef7a.png

 为什么for循环中envp没有写判断呢?因为我们刚刚说过,envp这个指针数组中最后一个指针指向的一定是NULL,而NULL在for循环中对应为假,所以不需要写判断语句。

91984d5470944dd896117db9c15d9955.png

 由于使用main函数的三个参数是c99标准下的,所以我们在编译后面加上c99。

0493d41210ec4fc88805e0a966a6dec6.png

 然后我们直接运行程序发现这里的环境变量与我们用env命令显示的一致。

总结:环境变量本质就是内存级的一张表,这张表由用户在登录系统的时候,进行给特定用户形成属于自己的环境变量表。环境变量中的每一个都有自己的用途,有的是进行路径查找的,有的是进行身份认证的,有的是进行动态库查找的,有的是用来进行确认当前路径等等,每一个环境变量都有自己特定的应用场景。那么环境变量对应的数据都是从哪来的呢?是从系统的相关配置文件中读取进来的。下面我们验证一下:

我们先用ctrl + ~进入家目录,然后输入指令ls -al查找文件:

e0a14d674ac247ba9d4c4c1b727fb701.png

 我们可以看到bash的两个shell脚本,然后我们用vim打开这个脚本:

ae34742d84d447578034c3d119f5a4f0.png

 我们用vim进入etc/bashrc,注意在etc目录下bashrc是全局的。

5463d7bebacc4306bfd430955fc36dfb.png

 比如我们命令行上的# 或者 $提示符就是这样编写的。  环境变量是通常具有全局属性的,当我们写了一个环境变量val=100,然后这个环境变量就会shell的表中,当我们给这个进程在开一个子进程的时候,shell中的这张表也会交给子进程,这样子进程中也就有了环境变量val=100,下面我们来证明一下:

946aac7ad9fc4dce8ad5b3cdc71bf470.png

 我们先自己导入一个环境变量,然后输入env命令查看:

97d7963b289b40c0badbd1e5bb70f892.png 我们看到确实将这个环境变量添加到系统中,下面我们修改一下代码进行演示:

17dd266e3a7b436f9bee421adfb364cc.png

getenv()函数是获取一个环境变量并打印 

02d0eb73320c493e99461da6c3318923.png 我们从上图中可以看到成功获取到了我们自己设的环境变量,我们前面讲过当我们运行一个进程的时候这个进程的父进程是bash,刚刚我们的环境变量是保存在系统中也就是说只有bash可以访问,但是现在这个子进程也可以使用就说明了环境变量是全局的,会由父进程传给子进程。

d9aed7534c1c46f2a3093c444c92f572.png

 我们定义了一个变量前面没有加export,然后我们在前面加$符号打印其内容发现也能正常打印

721859772cf748c09ecbc161b9eacd02.png

 下面我们用getenv获取一下这个环境变量:

a815b9ad3e4d4774a0e5ddc509c16cff.png

3886220543ad459d90366fcce00653ea.png 这个时候我们发现用函数获取环境变量获取不到我们刚刚定义的hello1,也就是说不带export定义的环境变量是不可以被getenv()获取到的,那么也就不可以被子进程继承,那么为什么加了export就能被继承呢?因为不加export定义的环境变量是不会被添加到环境变量表中,这样的变量被称为shell的本地变量,这种变量只能在shell内部有效。

b01629f725ca4cdba22c8b2362c99dd0.png

 因为hello1已经在shell本地了,所以前面加export可以直接将hello1添加到环境变量表,也就可以正常被子进程继承了。

接下来我们继续解释刚刚main函数的三个参数中的另外两个。

6919d0e5236a4f24b8c0fd25e610f666.png

 argv的使用与argc都有一个共同点,就是不需要在判断结束条件。

6e4188fc28384bdb91e521796a593cc6.png

如下图所示:

f97e681055f84c0492bef8c8f721e5be.png-a -b其实是参数选项,my2.24是可执行。那么这个操作有什么作用呢?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
//int main()
//{
//  int cnt = 10;
//  while (cnt--)
//  {
//    printf("这里在倒计时:%d\n",cnt);
//  }
//  return 0;
//}
void Usage(const char* name)
{printf("\nUsage:%s -[a|b|c]\n",name);exit(0);
}
int main(int argc,char* argv[])
{if (argc!=2) Usage(argv[0]);if (strcmp(argv[1],"-a")==0) printf("打印当前目录下的文件名\n");else if(strcmp(argv[1],"-b")==0) printf("打印当前目录下的详细信息\n");else if(strcmp(argv[1],"-c")==0) printf("打印当前目录下的文件名(包含隐藏文件)\n");else printf("其他功能,待开发\n");
//{
//  for (int i = 0;argv[i];i++)
//  {
//    printf("argv[%d]->%s\n",i,argv[i]);
//  }return 0;
}
//int main()
//{
//  printf("myenv:%s\n",getenv("hello1"));
//  return 0;
//}

 我们重新写一段代码,然后我们运行起来。

b4680554930146ad93724193fd4aab62.png

 启动软件后这个软件告诉我们使用方法是./my2.24 + abc任意一个字符

6ad89f683c6240bdbbe80480f81ad57f.png

 这样就能完成一个类似于打印目录的操作,这只是简单的演示实际上可以实现一些有用的东西。

 


总结

本篇文章相较于上一篇进程的概念多了很多需要实践的东西,比如测试进程的优先级,理解孤儿进程,学会理解环境变量并且可以自己添加环境变量,环境变量的获取,环境变量的修改等。下一篇继续更深入的学习linux的进程,即使进程这部分概念多也希望大家可以多多练习才能更深入的理解进程。

 

相关文章:

【linux】:进程状态(僵尸进程等)以及环境变量

文章目录 前言一.进程状态 进程的优先级二.环境变量总结前言 本篇文章是接着上一篇【linux】:进程概念的后续&#xff0c;对于有基础的同学可以直接看这篇文章&#xff0c;对于初学者来说强烈建议大家从上一篇的概念开始看起&#xff0c;上一篇主要解释了冯诺依曼体系以及操…...

【C语言——练习题】指针,你真的学会了吗?

✨✨✨✨如果文章对你有帮助记得点赞收藏关注哦&#xff01;&#xff01;✨✨✨✨ 文章目录✨✨✨✨如果文章对你有帮助记得点赞收藏关注哦&#xff01;&#xff01;✨✨✨✨一维数组练习题&#xff1a;字符数组练习题&#xff1a;字符指针练习题&#xff1a;二维数组练习题&am…...

Linux用户空间与内核空间通信(Netlink通信机制)

一&#xff0c;什么是Netlink通信机制 Netlink是linux提供的用于内核和用户态进程之间的通信方式。但是注意虽然Netlink主要用于用户空间和内核空间的通信&#xff0c;但是也能用于用户空间的两个进程通信。只是进程间通信有其他很多方式&#xff0c;一般不用Netlink。除非需要…...

3.3日报

今天写技术文档 跟需求对其 找负责人要上游数据接口&#xff0c;并处理更新时间问题 遇到的问题&#xff1a; 1.调用上游接口&#xff0c;需要token&#xff0c;而我的数据看板是不需要登录的&#xff0c;需要其他途径获取token 不同数据使用的接口不在一个项目中&#xff…...

并发编程-进程

并发编程-进程 进程创建启动 python提供了multiprocessing模块来支持多进程 multiprocessing.Process(targettask, args(arg,))用于创建进程 Process类相关方法 start() 启动进程join() 等待进程结束 启动子线程 【注意】线程启动代码块要放在__name__ __main__下 方式…...

LeetCode196_196. 删除重复的电子邮箱

LeetCode196_196. 删除重复的电子邮箱 一、描述 SQL架构 Create table If Not Exists Person (Id int, Email varchar(255)) Truncate table Person insert into Person (id, email) values (1, johnexample.com) insert into Person (id, email) values (2, bobexample.com…...

Auto.js Pro 替代品

Time : 2023年3月2日04:20:31 Mode : 持续更新中,排名不分先后.想起啥写啥 By : MemoryErHero NewTime: 2023年3月4日12:11:49 NO13. Autox.js文档&#xff1a; http://doc.autoxjs.com/ NO14. AutoJs6项目文档&#xff1a;https://github.com/SuperMonster003/AutoJs6 NO…...

红日(vulnstack)2 内网渗透ATTCK实战

环境配置 链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;wmsi 攻击机&#xff1a;kali2022.03 web 192.168.111.80 10.10.10.80 自定义网卡8&#xff0c;自定义网卡18 PC 192.168.111.201 10.10.10.201 自定义网卡8&#xff0c;自定义网卡18 DC 192.168.52.1…...

一个好的工程项目管理软件所包含的主要功能

工程项目管理软件哪个好&#xff1f;借助Zoho Projects强大的工程项目管理软件&#xff0c;您的团队可以在预算范围内按时交付。从质量保证到预算规划&#xff0c;Zoho Projects的工程项目管理平台旨在推动切实的成果是Zoho Projects工程项目管理软件的优势。 高质量的可交付成…...

【大数据监控】Grafana、Spark、HDFS、YARN、Hbase指标性能监控安装部署详细文档

目录Grafana简介下载软件包安装部署修改配置文件创建用户创建Systemd服务启动 GrafanaSpark应用监控 Graphite_exporterHDFS 监控YARN 监控HBase 监控Grafana 简介 Grafana 是一款开源的数据可视化工具&#xff0c;使用 Grafana 可以非常轻松的将数据转成图表(如下图)的展现形…...

面试题---CSS

面试题---CSS子绝父相下&#xff0c;子百分比的问题两栏布局问题三栏布局问题---圣杯问题(三栏&#xff0c;左右固定&#xff0c;中间自适应)。内联样式与块级样式的区别怎么让一个 div 水平垂直居中分析比较 display: none 、visibility: hidden、opacity: 0优劣和适用场景css…...

【C++】vector

目录 vector 1. vector的成员函数 1.1 构造、析构和赋值运算符重载 1.1.1 构造函数 1.1.2 析构函数 1.1.3 赋值运算符重载 1.2 迭代器 1.3 容量 1.4 元素访问 1.4.1 遍历方法 1.5 修改器 1.6 配置器 2. vector的非成员函数 vector 1. vector的成员函数 1.1 构造…...

RocketMQ安装

RocketMQ安装 安装前准备 1.RocketMQ是使用Java语言编写的所以在安装该MQ前需要Java环境。 2.准备好RocketMQ ​ RocketMQ运行版本下载地址&#xff1a; https://www.apache.org/dyn/closer.cgi?pathrocketmq/4.7.1/rocketmq-all-4.7.1-bin-release.zip ​ RocketMQ源码版…...

Spring——什么是IOC?

一、原则高内聚、低耦合二、什么是IOC&#xff1f;控制反转&#xff0c;把对象创建和对象之间的调用过程&#xff0c;交给spring进行管理三、使用IOC的目的是什么&#xff1f;降低耦合&#xff08;谁和谁的耦合&#xff1f;&#xff1f;如何降低的&#xff1f;&#xff09;原来…...

力扣(LeetCode)430. 扁平化多级双向链表(2023.03.04)

你会得到一个双链表&#xff0c;其中包含的节点有一个下一个指针、一个前一个指针和一个额外的 子指针 。这个子指针可能指向一个单独的双向链表&#xff0c;也包含这些特殊的节点。这些子列表可以有一个或多个自己的子列表&#xff0c;以此类推&#xff0c;以生成如下面的示例…...

条款13:优先考虑const_iterator而非iterator

STL const_iterator等价于指向常量的指针&#xff08;pointer-to-const&#xff09;。它们都指向不能被修改的值。标准实践是能加上const就加上&#xff0c;这也指示我们需要一个迭代器时只要没必要修改迭代器指向的值&#xff0c;就应当使用const_iterator。 上面的说法对C11…...

23考研 长安大学846计算机考研复试《数据库》

长安大学846计算机考研,复试历年真题《数据库》。 目录: (1)数据库复习 (2)专业面试 (3)2017-2020年历年复试题 (4)复试的一些心得 数据库复习: 刚开始复试的时候,先把教材学习一遍(《数据库系统概念》 王珊 第五版),课后习题自己做一遍,网上有卖这本书的 配套…...

Android 9.0 系统去掉省电模式

1.概述 在9.0的系统rom开发定制化工作中,在系统中系统设置里面省电模式的选择中,有智能省电模式 省电模式 和超级省电模式三种 由于对rom系统做了大量定制功能开发,所以会在进入省电模式的时候 会出现某些不必要的问题,由于产品开发需求, 就要求去掉省电模式 不让平板进入…...

3 mmmmm

全部 答对 答错 单选题 7. 项目经理通知敏捷团队成员&#xff0c;由于意外的个人问题&#xff0c;产品负责人将不能参加即将到来的冲刺审查。这种情况下最可能的结果是什么&#xff1f; A project manager informs the agile team members that, due to unexpected personal …...

nvidia Jetson nano Linux内核编译

今天编译了nvidia 的jetson nano的内核。在网上找到的资料都比较老了。现在官网的最新版本是35.1.结合之前看到的博客的内容。关键是内核源码和交叉编译器的下载。找到官方文档后,编译成功!并且官方的文档是有一个编译脚本的。看之前的资料都是给出的命令,不知道这个nvbuild…...

理想汽车2023年销量冲击30万辆有戏吗?

出品 | 何玺 排版 | 叶媛 2月27日理想汽车发布财报&#xff0c;数据表明&#xff0c;2022年理想营收和销量双双大涨。在财报会议上&#xff0c;理想汽车CEO李想表示&#xff0c; 2023年的销量预期为30万辆。 那么&#xff0c;理想汽车2023年销量冲击30万辆的目标能实现吗&…...

借助CatGPT让turtlesim小乌龟画曲线

注意这里是CatGPT&#xff0c;不等同OpenAI的ChatGPT&#xff0c;但是用起来十分方便&#xff0c;效果也还行。详细说明ROS机器人turtlesim绘制曲线需要注意哪些ROS机器人turtlesim绘制曲线需要注意以下几点&#xff1a;绘制曲线前需要设置好turtlesim的初始位置和方向&#xf…...

Java面试总结(四)

synchroize的实例、静态、代码块的锁对象 修饰实例方法 修饰静态方法 修饰代码块 1、修饰实例方法 &#xff08;锁当前对象实例&#xff09; 给当前对象实例加锁&#xff0c;进入同步代码前要获得 当前对象实例的锁 。 synchronized void method() {//业务代码 }2、修饰静…...

强强联合,再强的英伟达NVIDIA也不落俗套

强强联合&#xff0c;全球科技领域永恒的话题【科技明说 &#xff5c; 每日看点】前些天&#xff0c;我看到GPU领域的英伟达(Nvidia)与微软(Microsoft)做了一项十年期的云计算协议&#xff0c;起初我以为微软Microsoft Azure与英伟达GPU方面有所合作&#xff0c;其实不然&#…...

maven使用心得

maven 配置文件默认在 ~/.m2/settings.xml maven命令行 mvn clean install -Dmaven.test.skiptrue -s ~/.m2/settings.xml 往本地仓库加jar包 命令形如&#xff1a; mvn install:install-file -DgroupIdcom.lee.net -DartifactIdMyToolIdl -Dversion1.0.0-SNAPSHOT -Dpac…...

【算法题】1958. 检查操作是否合法

插&#xff1a; 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 坚持不懈&#xff0c;越努力越幸运&#xff0c;大家一起学习鸭~~~ 题目&#xff1a; 给你一个下标从 0 开始的 8 x 8 网…...

十一、GoF之代理模式

1 对代理模式的理解 【在程序中&#xff0c;对象A和对象B无法直接交互时。】 【在程序中&#xff0c;功能需要增强时。】 【在程序中&#xff0c;目标需要被保护时】 业务场景&#xff1a;系统中有A、B、C三个模块&#xff0c;使用这些模块的前提是需要用户登录&#xff0c;也…...

MySQL5.6和JVM(1.6)调优

MySQL5.6调优 目标了解什么是优化掌握优化查询的方法掌握优化数据库结构的方法掌握优化MySQL服务器的方法什么是优化?合理安排资源、调整系统参数使MySQL运行更快、更节省资源。<...

【汇编】三、寄存器(一只 Assember 的成长史)

嗨~你好呀&#xff01; 我是一名初二学生&#xff0c;热爱计算机&#xff0c;码龄两年。最近开始学习汇编&#xff0c;希望通过 Blog 的形式记录下自己的学习过程&#xff0c;也和更多人分享。 上篇系列文章链接&#xff1a;【汇编】二、预备知识&#xff08;一只 Assember 的…...

TFT通信协议解析与应用

TFTP&#xff08;Trivial File Transfer Protocol&#xff09;是一种简单的文件传输协议&#xff0c;常用于在本地网络上的设备之间传输小型文件。 通信大致过程 TFTP通信过程如下&#xff1a; TFTP通信双方建立连接&#xff1a;TFTP客户端与TFTP服务器建立连接。TFTP服务器监…...