Linux:进程概念(三.详解进程:进程状态、优先级、进程切换与调度)

news2024/11/15 20:45:28

上次讲了进程这些内容:Linux:进程概念(二.查看进程、父进程与子进程、进程状态详解)


文章目录

  • 1.Linux中的进程状态
    • 1.1前台进程和后台进程
    • 运行状态
    • 睡眠状态
    • 磁盘休眠状态
    • 停止状态
      • kill指令—向进程发送信号
    • 死亡状态
  • 2.僵尸进程
    • 2.1僵尸状态
    • 2.2僵尸进程
    • 2.3僵尸进程危害
  • 3.孤儿进程
  • 4.进程的优先级
    • 概念
    • 查看进程优先级
    • PRI(优先级)和NI(nice)
    • 更改nice来间接改变优先级
  • 5.进程其他重要概念
  • 6.进程的切换与调度
    • 进程切换
    • 进程调度


1.Linux中的进程状态

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): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。

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

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

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

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

  • Z僵尸状态(zombie):下面详讲它

1.1前台进程和后台进程

在Linux中,可以将进程分为前台进程和后台进程,它们的区别在于与终端的交互方式和执行状态。

  1. 前台进程:会有+

    • 前台进程是当前正在与用户交互的进程,它会占用终端的输入和输出。
    • 当用户在终端启动一个程序时,该程序通常成为前台进程,用户可以看到程序的输出,并且可以与程序进行交互。
    • 前台进程会阻塞终端,直到该进程执行完毕或者暂停。
    • 用户可以通过按下Ctrl + C来中断前台进程的执行。
  2. 后台进程:没有+

    • 后台进程是在后台执行的进程,不会占用终端的输入和输出。
    • 用户可以在命令行中在命令后面加上"&"符号,将进程放入后台执行
    • 后台进程不会阻塞终端,用户可以继续输入其他命令
    • 用户可以使用命令bg将一个前台进程转为后台进程,或者使用命令jobs查看当前所有的作业(包括前台和后台)。
    • 使用kill 进程ID命令关闭对应的后台进程,比如kill 1234

运行状态

运行状态(Running)是进程可以被调度执行的状态。当一个进程处于运行状态时,它的代码正在被 CPU 执行,即正在运行指令并处理各种任务。在 Linux 中,通常用 R 表示进程处于运行状态。

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

在这里插入图片描述

睡眠状态

就是我们上次学习的阻塞状态,在Linux中,进程的睡眠状态(Sleeping)是指进程因等待某些事件而暂时停止执行。这个状态有时也被称为可中断睡眠(Interruptible Sleep),因为进程在这种状态下可以被中断,例如通过接收信号来唤醒。

睡眠状态的进程通常在等待某些事件的完成,例如:

  • 等待某个I/O操作的完成,比如从磁盘读取数据。
  • 等待某个信号的到达,例如等待用户输入或其他进程发送的信号。
  • 等待某个条件的满足,比如等待某个锁的释放或某个共享资源的可用性。

需要注意的是,睡眠状态的进程是可以被中断的,也就是说,在等待事件的过程中,如果接收到一个信号,进程可能会被唤醒并处理该信号,之后可能会继续等待或执行其他操作。我们使用Ctrl+c可以中断进程,因此,这种状态也称为可中断睡眠

#include<stdio.h>
#include<unistd.h>
int main()
{
    int a=0;
    while(1)
    {
        printf("%d",a);
        sleep(2);
    }
    return 0;
}

在这里插入图片描述

在这个程序中,主循环是一个无限循环 while(1),它不会主动放弃 CPU,因此进程会一直处于运行状态(R)。但是,在每次循环迭代中,程序会调用 printf 函数打印 a 的值,并使用 sleep(2) 函数让进程休眠 2 秒。

sleep(2) 调用期间,进程暂时停止执行,等待指定的时间结束后再继续执行。虽然进程在休眠期间处于不活动状态,但是它并没有主动释放 CPU。因此,进程会被标记为睡眠状态(S),表示它正在等待特定事件的完成,即等待 sleep 函数定时器计时结束。

但是如果我们把sleep()去掉后,会发现还是S状态

在这样的程序中,主循环是一个无限循环 while(1),它不会主动放弃 CPU,因此进程会一直处于运行状态(R)。但是,由于 printf 函数涉及输出操作,这可能会导致进程在等待标准输出设备的 I/O 操作完成时陷入睡眠状态(S)。

当程序运行时,printf 函数将数据输出到标准输出设备(通常是终端),并且在数据传输过程中,可能需要等待设备的响应。在这段等待期间,进程暂时停止执行,处于睡眠状态。因此,即使主循环一直在运行,但是由于进程在某些时刻需要等待设备响应,因此会被标记为睡眠状态(S)。(CPU执行是很快的)

在这里插入图片描述

磁盘休眠状态

也是阻塞状态。D磁盘休眠状态(Disk sleep)是Linux系统中的一种进程状态,有时也称为不可中断睡眠状态(uninterruptible sleep)。进程进入这种状态通常是因为正在等待某些IO操作的完成,比如磁盘读写操作,网络请求等。在D状态下的进程是无法被中断或者唤醒的,直到IO操作完成为止。

  1. 进程状态
    • 当一个进程被阻塞在等待IO操作完成的情况下,它会被标记为D状态。这种状态下的进程无法响应信号,也无法被中断。
  2. 原因
    • 进程进入D状态通常是因为正在等待硬件设备的响应。比如,一个进程正在等待硬盘读取数据,但是硬盘响应较慢,导致进程无法继续执行。
  3. 解决方法
    • 通常情况下,D状态的进程会在IO操作完成后自动恢复,进程会从D状态转为可运行状态。如果进程长时间处于D状态,可能需要检查硬件设备是否正常,或者尝试重新启动系统。

也可以理解磁盘休眠状态的进程是有免死金牌的,能防止CPU因为资源不足而删除这个正在等待的进程

因此,即使系统资源紧张或CPU负载高,磁盘休眠状态下的进程仍然会被系统保留,不会被强制删除。这种机制确保了IO操作的完整性和系统的稳定性。

停止状态

在Linux系统中,当一个进程接收到SIGSTOP信号时,它会被暂停(停止)执行,进入停止状态。在这种状态下,进程的执行被暂时挂起,不会继续执行,也不会被调度到CPU上运行。

停止状态下的进程不会消耗CPU资源,也不会响应任何信号,直到接收到SIGCONT信号后才会继续执行。停止状态的进程可以通过ps命令或者类似的工具查看,通常会显示为T状态。

要将一个进程从停止状态恢复到运行状态,可以向该进程发送SIGCONT信号。这样进程就会从停止状态恢复到运行状态,继续执行

kill指令—向进程发送信号

在Linux系统中,kill指令用于向进程发送信号。通过kill指令,可以向指定的进程发送不同的信号,从而影响进程的行为。常用的kill指令格式如下:

kill [options] <PID>

其中,<PID>是要发送信号的进程的进程ID(Process ID)。可以使用ps指令或者pgrep指令来查找进程的进程ID。

  • -9:发送SIGKILL信号,强制终止进程。

  • -15(或不加选项):发送SIGTERM信号,请求进程正常终止。

  • kill -l是用来列出系统支持的信号列表的命令

  • -19 SIGSTOP(编号为19):发送SIGSTOP信号会使进程停止执行,进程将被挂起,直到接收到SIGCONT信号继续执行。SIGSTOP信号不能被捕获、忽略或阻塞,是一种强制停止进程的信号。

  • -18 SIGCONT(编号为18):发送SIGCONT信号会使之前被停止的进程继续执行。这个信号用于恢复被SIGSTOP或者类似信号暂停的进程的执行。

在这里插入图片描述

在这里插入图片描述

死亡状态

对应的就是我们之前讲解的终止状态

在Linux系统中,"死亡状态(dead)"通常指的是进程已经终止(terminated)并且退出,但其进程描述符(process descriptor)还未被释放。这种状态通常在进程终止后,其父进程还未对其进行处理或回收资源时出现。

当一个进程终止后,其进程描述符会保留一段时间,直到父进程调用wait()waitpid()等系统调用来回收子进程的资源。在这段时间内,进程的状态会被标记为"死亡状态(dead)"。一旦父进程回收了子进程的资源,进程描述符就会被释放,进程完全被清除。

因为是一个瞬间的动作,我们很难看到该状态


2.僵尸进程

2.1僵尸状态

在Linux系统中,当一个进程终止后,其进程描述符==(PCB并不会立即被释放)。此时,该进程会变成一个僵尸进程(Zombie Process)。僵尸进程是指一个进程已经终止==,但其父进程还未对其进行处理或回收资源

在Linux系统中,当父进程读取了子进程的退出状态后,子进程的状态会从僵尸状态(Zombie)变为终止状态(Terminated),通常用X表示。这意味着父进程已经处理了子进程的退出状态信息,并且子进程的资源已经被释放,不再占用系统资源。因此,及时处理子进程的退出状态是非常重要的,可以避免僵尸进程的积累,提高系统的稳定性和性能。

而bash会自动读取子进程的退出状态

2.2僵尸进程

  • 僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程(使用wait()系统调用,后面讲)没有读取到子进程退出的返回代码时就会产生僵死(尸)进程

  • 僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码

  • 所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态

2.3僵尸进程危害

  1. 进程的退出状态对于父进程来说很重要,因为它告诉父进程子进程执行任务的结果。如果父进程不读取子进程的退出状态,子进程就会一直处于僵尸(Zombie)状态。
  2. 退出状态是需要被维护的数据,保存在进程控制块(task_struct或PCB)中。因此,即使进程处于僵尸状态,其退出状态信息也需要被维护(PCB不会被释放,进程控制块(task_struct或PCB)中保存了进程的重要信息)。
  3. 如果一个父进程创建了很多子进程但不回收它们,会导致内存资源的浪费。因为每个进程都有自己的进程控制块,不回收子进程会导致内存泄漏。

3.孤儿进程

孤儿进程是指父进程先于子进程结束而结束,导致子进程成为孤儿进程。在Linux系统中,孤儿进程会被init进程(进程ID为1的进程)接管。当父进程先于子进程结束时,子进程的父进程ID会被修改为1,即init进程的进程ID,这样子进程就成为了孤儿进程。

  1. 孤儿进程的父进程ID会被修改为1,即init进程的进程ID
  2. 孤儿进程会被init进程接管,init进程会负责回收孤儿进程的资源。
  3. 孤儿进程的父进程结束后,其父进程ID会被修改为1,但其依然可以正常运行,直到自己结束或被init进程接管
  4. 这种领养机制保证了即使父进程终止,子进程仍然能够正常运行并被系统管理

孤儿进程的产生通常发生在父进程没有等待子进程结束就提前结束的情况下。为了避免产生孤儿进程,父进程在创建子进程后应该等待子进程结束,并及时处理子进程的终止状态。这样可以确保子进程在父进程结束时能够正常退出,而不会成为孤儿进程。

4.进程的优先级

概念

  • cpu资源分配的先后顺序,就是指进程的优先权(priority)。

  • 优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。

  • 还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能。

  • 系统通常会根据进程的实际需求和系统负载来动态调整优先级。较高优先级的进程将更频繁地获得CPU时间片,从而更快地执行,而较低优先级的进程可能会等待更长的时间才能获得CPU执行时间。

  1. Linux中优先级默认是80
  2. Linux优先级是可以被修改的,Linux的优先级的范围 [60,99],
  3. 数字越小,优先级越高
task_struct
{
	//...
	int PRI;
	int nice;
	//...
};

查看进程优先级

ps -al
  • -a 选项:显示所有进程,包括其他用户的进程。默认情况下,ps 命令只显示当前用户的进程,使用 -a 选项可以显示所有用户的进程。

  • -l 选项:以长格式显示进程信息。长格式包括更多的字段,如进程状态、进程 ID、父进程 ID、优先级、CPU 使用情况、内存使用情况等。

在这里插入图片描述

  • UID : 代表执行者的身份

  • PID : 代表这个进程的代号

  • PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号

  • PRI :代表这个进程可被执行的优先级,其值越小越早被执行

  • NI :代表这个进程的nice值

PRI(优先级)和NI(nice)

  • PRI也还是比较好理解的,即进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序,此值越小进程的优先级别越高

  • 那NI就是我们所要说的nice值了,其表示进程可被执行的优先级的修正数值

    • nice 值的确是影响进程优先级的修正因子,通过调整 nice 值,可以间接地影响进程的优先级,从而影响其在CPU上的执行顺序。
  • PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为:PRI(new)=PRI(old)+nice

  • 这样,当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行

  • 所以,调整进程优先级,在Linux下,就是调整进程nice值

  • nice其取值范围是-20至19,一共40个级别

为什么要有-20到19的这个限制?

  1. 如果没有这个限制,那么就有人会把自己使用的优先级调的特别特别高,把别人的进程调低,这样显然不好
  2. 进程饥饿问题是指在多任务系统中,优先级较高的进程持续占用CPU资源,导致优先级较低的进程无法及时获得CPU时间片,从而长时间处于等待状态,无法执行。这种情况下,低优先级的进程可能会长时间等待CPU资源,无法完成其任务,造成资源浪费和系统性能下降

更改nice来间接改变优先级

top:进入top后按“r”–>输入进程PID–>输入nice值

使用 top 命令可以实时监视系统的运行情况,包括进程的资源占用情况、进程列表等。按下 r 键后,可以对指定进程的优先级进行调整。

在按下 r 键后,按照提示输入要调整优先级的进程的PID,然后输入要为其设置的新的 nice 值。输入完毕后,top 将会尝试修改指定进程的优先级,根据新的 nice 值重新计算其优先级。这样可以实现对指定进程执行优先级的调整。

5.进程其他重要概念

  1. 竞争性:指系统中进程的数量多于可用的CPU资源。由于资源有限,进程之间会竞争CPU、内存、IO等资源。为了高效地完成任务,进程之间需要根据优先级进行竞争,以便合理地分配资源并提高系统性能。

  2. 独立性:多进程运行时,每个进程都有自己的内存空间和执行环境,彼此之间相互独立,互不干扰。这意味着一个进程的错误或异常不会直接影响其他进程的正常运行,提高了系统的稳定性和可靠性。

  3. 并行:多个进程在多个CPU上同时执行(我们一般遇不到),每个CPU负责处理一个或多个进程。这样可以加快任务的执行速度,提高系统的吞吐量和性能。

  4. 并发:多个进程在单个CPU上交替执行,通过进程切换的方式,让多个进程在一段时间内都得以推进。虽然在任意时刻只有一个进程在CPU上执行,但由于进程切换的快速性,给人的感觉就像是多个进程在同时执行一样。并发可以提高系统的响应速度和资源利用率。

现代操作系统采用时间片轮转的方式来调度进程执行,而不是等待一个进程的代码完全执行完毕后再切换到下一个进程。这种方式能够实现多任务的并发执行,提高系统的响应速度和资源利用率。

  1. 时间片(Time Slice): 时间片是操作系统分配给每个进程的执行时间段。一旦一个进程的时间片用完,操作系统就会将CPU的控制权交给另一个就绪状态的进程,从而实现进程的切换和并发执行。
  2. 轮转调度(Round-Robin Scheduling): 时间片轮转调度算法是一种简单而高效的调度算法,它会将就绪队列中的进程按照先来先服务的原则排队,并为每个进程分配一个固定长度的时间片。当一个进程的时间片用完后,操作系统会将其移到队列的末尾,然后继续执行下一个就绪进程。

6.进程的切换与调度

进程的切换与调度是操作系统中非常重要的部分,它涉及到如何有效地利用CPU资源,保证系统的响应速度和吞吐量。

进程切换

在这里插入图片描述

进程切换指的是从一个正在执行的进程切换到另一个进程的过程。当操作系统决定将CPU的控制权从当前进程转移到另一个进程时,就需要进行进程切换。进程切换包括以下几个关键步骤:

  1. 上下文保存: 当操作系统决定要切换到另一个进程时,首先需要保存当前进程的上下文信息,包括程序计数器、寄存器内容、栈指针等。这些信息存储在进程的控制块(PCB)中。

  2. 选择新进程: 在确定要切换到哪个新进程之前,操作系统会根据调度算法从就绪队列中选择一个合适的进程。这个选择可能基于进程的优先级、先到先服务(FIFO)、轮转法等。

  3. 加载新进程的上下文: 一旦确定了新进程,操作系统就会从其对应的PCB中恢复该进程的上下文信息。这包括将新进程的程序计数器值加载到CPU中,以便执行新进程的代码。

进程调度

在这里插入图片描述

进程调度是操作系统根据一定的调度策略从就绪队列中选择下一个要执行的进程的过程。调度策略的选择会影响系统的性能、响应速度和资源利用率。

  1. 进程队列数组 queue[140]:这个数组用于存储不同优先级的进程队列。每个队列按照先进先出(FIFO)规则进行排队调度。数组的下标表示进程的优先级,因此可以直接根据优先级来访问对应的进程队列,提高了访问效率。

  2. 进程队列状态位图 bitmap[5]:为了快速判断哪些队列是非空的,使用了一个位图来表示每个队列的状态。每个比特位对应一个队列,如果该队列非空,则对应的比特位为1;否则为0。这样,查找非空队列的操作变得高效,时间复杂度为常数级别。

  3. active指针和expired指针:这两个指针用于指示当前活跃队列和过期队列。随着调度的进行,它们的内容可以交换,从而实现活跃队列和过期队列的动态切换。

  4. 活跃队列和过期队列:活跃队列中包含当前活跃的进程,而过期队列包含一段时间内未被调度的进程。Linux 内核根据需要从活跃队列和过期队列中选择进程进行调度,以平衡优先级和资源利用效率。

活动队列

  • 时间片还没有结束的所有进程都按照优先级放在该队列

  • nr_active: 总共有多少个运行状态的进程

  • queue[140]: 一个元素就是一个进程队列,相同优先级的进程按照FIFO规则进行排队调度,所以,数组下标就是优先级!

  • bitmap[5]:一共140个优先级,一共140个进程队列,为了提高查找非空队列的效率,就可以用5*32个比特位表示队列是否为空,这样,便可以大大提高查找效率

  • 从该结构中,选择一个最合适的进程,过程是怎么样呢?

    1. 从0下表开始遍历queue[140]
    2. 找到第一个非空队列,该队列必定为优先级最高的队列
    3. 拿到选中队列的第一个进程,开始运行,调度完成

过期队列

  • 过期队列和活动队列结构一模一样
  • 过期队列上放置的进程,都是时间片耗尽的进程、
  • 当活动队列上的进程都被处理完毕之后,对过期队列的进程进行时间片重新计算
  1. O(1) 调度算法:Linux 内核的调度器通常采用 O(1) 调度算法(使用了位图(bitmap)来实现),该算法在常数时间内选择下一个要执行的进程,而不受进程数量的影响。这确保了调度器的高效性,使得系统在任何负载情况下都能快速响应。

好啦,进程相关的知识,也大概梳理完毕了。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

零售全渠道营销业务链分析,让企业管控能力大幅加强!

对于传统的、规模化的零售快消企业来讲&#xff0c;面临着很大的渠道管理和建设问题&#xff0c;如何尽快实现整个营销体系的全渠道数字化转型是当务之急、重中之重。 面对错综分散的经销商&#xff0c;零售快消企业订货流程会越复杂&#xff0c;加之对门店管理较为粗放&#…

武汉星起航:亚马逊母亲节选品指南,热销产品助卖家赢取节日商机

随着母亲节的脚步日益临近&#xff0c;全球消费者纷纷开始为这一特殊的节日挑选礼物&#xff0c;以表达对母亲的深深感激和无尽爱意。作为跨境电商的重要平台&#xff0c;亚马逊凭借其丰富的商品种类和便捷的购物体验&#xff0c;成为消费者选购母亲节礼物的首选之地。那么&…

【数据结构陈越版笔记】第1章 概论

我最近准备以陈姥姥的数据结构教材为蓝本重新学一下数据结构&#xff0c;写一下读书笔记 第1章 概论 1.1 引子 概论中首先描述了&#xff0c;数据结构的定义没有具体的定义&#xff0c;初学者可以不用管这个定义的问题&#xff0c;但是我理解的和维基百科的说法是一样的“数…

[已解决]ModuleNotFoundError: No module named ‘tqdm‘

&#x1f60e; 作者介绍&#xff1a;我是程序员行者孙&#xff0c;一个热爱分享技术的制能工人。计算机本硕&#xff0c;人工制能研究生。公众号&#xff1a;AI Sun&#xff0c;视频号&#xff1a;AI-行者Sun &#x1f388; 本文专栏&#xff1a;本文收录于《AI实战中的各种bug…

如何批量删除多个不同路径的文件但又保留文件夹呢

首先&#xff0c;需要用到的这个工具&#xff1a; 度娘网盘 提取码&#xff1a;qwu2 蓝奏云 提取码&#xff1a;2r1z 1、我准备了三个文件夹&#xff08;实际操作的时候可能是上百个文件夹&#xff0c;无所谓&#xff09;&#xff0c;里面都放了两个图片 2、然后打开工具&am…

RustDesk 自建服务器部署和使用教程

RustDesk 是一个强大的开源远程桌面软件&#xff0c;是中国开发者的作品&#xff0c;它使用 Rust 编程语言构建&#xff0c;提供安全、高效、跨平台的远程访问体验。可以说是目前全球最火的开源远程桌面软件了&#xff0c;GitHub 星星数量达到了惊人的 64k&#xff01; 与 Team…

AIGC|将GPTBots与10000+主流软件连接,实现应用场景全覆盖

一、自动化工作流的无限可能&#xff0c;由AI带来 当前市场上存在许多自动化工作流工具&#xff0c;这些工具在很大程度上提升了人们的工作效率&#xff0c;为企业节省了大量时间和人力成本。然而&#xff0c;这些工具并非万能&#xff0c;它们在实际应用中仍存在一定的局限性…

如何在自己的服务器上快速搭建第一个网站(其一)

根据上篇文章相信很多人以及成功搭建服务器啦。今天我们讲下如何在自己的服务器快速搭建第一个网站的一些重要配置&#xff0c;以及搭建网站的必备环境。干货满满&#xff0c;希望大家能够关注点赞收藏。 我会不定期更新一些实用的工具&#xff0c;欢迎大家私信评论喔&#xf…

工作中使用Optional处理空指针异常

工作中使用Optional处理空指针异常 实体类以前对空指针的判断Optional处理空指针测试结果 实体类 package po;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;import java.io.Serializable;Data AllArgsConstructor NoArgsConstruct…

kafka生产者消费者举例

文章目录 kafka介绍生产者消费者例子一、生产者二、消费者三、效果 KafkaTemplate KafkaListener kafka介绍 Kafka 是一款分布式流处理平台&#xff0c;它被设计用于高吞吐量、持久性、分布式的数据流处理。 Kafka 简介&#xff1a; Kafka 是一个高吞吐、分布式、基于发布 订阅…

NSS刷题

[SWPUCTF 2021 新生赛]jicao 类型&#xff1a;PHP、代码审计、RCE 主要知识点&#xff1a;json_decode()函数 json_decode()&#xff1a;对JSON字符串解码&#xff0c;转换为php变量 用法&#xff1a; <?php $json {"ctf":"web","question"…

2024年数维杯B题完整代码和思路论文讲解与分析

2024数维杯数学建模完整代码和成品论文已更新&#xff0c;获取↓↓↓↓↓ https://www.yuque.com/u42168770/qv6z0d/bgic2nbxs2h41pvt?singleDoc# 2024数维杯数学建模B题45页论文和代码已完成&#xff0c;代码为全部问题的代码 论文包括摘要、问题重述、问题分析、模型假设、…

怎么让电脑耳机和音响都有声音

电脑耳机音响不能同时用没声音怎么办 一般来说&#xff0c;重新开机后问题能够得到解决。右击“我的电脑”---“属性”---“硬件”---“设备管理器”&#xff0c;打开“声音、视频和游戏控制器”有无问题&#xff0c;即看前面有没有出现黄色的“”。 如果您的 电脑 耳机能正常…

SQL注入(sqli-labs第一关)

sqli-labs第一关 方法一&#xff1a;手工注入 来到第一关&#xff0c;图上说我们需要一个数字的参数 于是我们先手工注入?id1 and 11 跟?id1 and 12发现页面没有报错 每张截图上面页面中有select查询语句&#xff0c;这是我在第一关的源码中加上了echo "$sql ";…

基于UDP协议Python通信网络程序(服务器端+客户端)及通信协议在自动驾驶场景应用示例

一、UDP协议 UDP&#xff08;用户数据报协议&#xff09;是一种无连接的传输层协议&#xff0c;具有简单、高效的特点&#xff0c;适用于一些对数据可靠性要求不高的应用场景。UDP的主要特点包括无连接、不可靠和面向数据报。这意味着在发送数据之前不需要建立连接&#xff0c…

【Spring之依赖注入】2. Spring处理@Async导致的循环依赖失败问题

使用异步Async注解后导致的循环依赖失败详解 1 问题复现1.1 配置类1.2 定义Service1.3 定义Controller1.4 启动springboot报错 2.原因分析&#xff1a;看Async标记的bean注入时机2.1 循环依赖生成过程2.2 自检程序 doCreateBean方法 3.解决方案3.1 懒加载Lazy3.1.1 将Lazy写到A…

根据部门id删除该部门下的员工(事务)

application.properties&#xff1a; 或&#xff1a; application.yml&#xff1a; 新表&#xff1a; 日志对象类&#xff1a; 日志service类&#xff1a; 日志service接口&#xff1a; 日志mapper类&#xff1a; 部门service类&#xff1a; 员工mapper类&#xff1a;

某大型集团SAP数字化转型方案(95页PPT)

一、资料介绍 《某大型集团SAP数字化转型方案》是一份详尽的95页PPT资料&#xff0c;旨在为某大型集团提供一套全面而深入的SAP数字化转型方案。该方案紧密结合了集团的业务特点和发展需求&#xff0c;以SAP系统为核心&#xff0c;通过数字化技术的运用&#xff0c;实现业务流…

【redis】Redis五种常用数据类型和内部编码,以及对String字符串类型的总结

˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如…

ESP32引脚入门指南(七):从理论到实践(IIC)

引言 IIC&#xff08;Inter-Integrated Circuit&#xff09;&#xff0c;又称为IC&#xff0c;是一种简单而高效的多主控器串行通信协议&#xff0c;常用于微控制器和各种外围设备之间的通信。在ESP32系列芯片中&#xff0c;IIC协议被广泛应用于连接各种传感器、存储器和其他支…