Linux:/proc/kmsg 与 /proc/sys/kernel/printk_xxx

目录

  • 前言
  • 一、/proc/kmsg
    • 1、简介
    • 2、如何修改内核日志缓冲区
    • 3、dmesg
      • klogctl 函数(来源于 man 手册)
    • 4、扩展阅读
  • 二、 /proc/sys/kernel/printk_xxx
  • 三、/dev/kmsg

前言

  本篇文章将为大家介绍与 Linux 内核日志相关的一些控制文件,共同学习!

一、/proc/kmsg

1、简介

  /proc/kmsg 是一个特殊的文件,它提供了内核消息缓冲区的访问,这个缓冲区包含了内核产生的所有消息,包括各种调试和错误信息,如内核的启动打印。/proc/kmsg 文件通常只能被 root 用户或具有相应权限的用户读取。这个文件通常被用于调试和故障排除,因为它可以提供关于内核发生事件的详细信息。
在这里插入图片描述
  注意:这是一个缓冲区,所以其内的数据是会被刷新覆盖的!!!

  一般情况下,你可以使用以下方式来使用 /proc/kmsg 文件:

1、读取内核消息:你可以使用命令行工具如 `cat``dmesg` 来查看和读取`/proc/kmsg`文件
中的内核消息。例如,使用以下命令可以显示最近的内核消息:
   cat /proc/kmsg
这样做可以帮助你查看内核启动时的各种信息、硬件错误、系统调试等。

需要注意的是,`/proc/kmsg` 文件一般只能被 root 用户或具有相应权限的用户访问,因此在使用
时请确保你有足够的权限。此外,了解内核消息的解释和上下文对正确理解和利用 `/proc/kmsg` 中
的信息非常重要。

2、如何修改内核日志缓冲区

  有时候我们发现,dmesg看到的日志信息缺少了很多,或者存储的很少,这个是因为内核日志缓冲区设置的较小,无法存储更多的内容,可以适当调整该缓冲区的大小。

  建议不要调整的过大,正常的产品使用128KB即可,若是自己调试排查问题可以设置的大一点,比如2MB,根据自己的物理内存资源合理设置。
在这里插入图片描述

3、dmesg

  /proc/kmsg 文件和 dmesg 命令之间有着紧密的关系。

  /proc/kmsg 文件提供了对内核消息缓冲区的直接访问,通过读取该文件可以查看最近的内核消息。dmesg 命令是一个通用命令行工具,主要用于显示和控制内核环缓冲区。使用 dmesg 命令可以更方便地查看内核日志消息,包括从开机到当前时间内的所有内核日志消息。

  实际上,dmesg 命令背后的实现原理也是通过读取 /proc/kmsg 文件来获取内核消息的。当我们在终端中执行 dmesg 命令时,它会读取 /proc/kmsg 文件的内容并将其显示在终端上。

  因此,可以说 /proc/kmsg 文件是 dmesg 命令的底层实现之一。在使用 dmesg 命令的时候,实际上是在调用 /proc/kmsg 文件提供的接口来获取内核日志。
在这里插入图片描述

以下文件来自busybox源码:busybox\util-linux\dmesg.c

/* vi: set sw=4 ts=4: */
/*
 *
 * dmesg - display/control kernel ring buffer.
 *
 * Copyright 2006 Rob Landley <rob@landley.net>
 * Copyright 2006 Bernhard Reutner-Fischer <rep.nop@aon.at>
 *
 * Licensed under GPLv2, see file LICENSE in this source tree.
 */
//config:config DMESG
//config:	bool "dmesg (3.7 kb)"
//config:	default y
//config:	select PLATFORM_LINUX
//config:	help
//config:	dmesg is used to examine or control the kernel ring buffer. When the
//config:	Linux kernel prints messages to the system log, they are stored in
//config:	the kernel ring buffer. You can use dmesg to print the kernel's ring
//config:	buffer, clear the kernel ring buffer, change the size of the kernel
//config:	ring buffer, and change the priority level at which kernel messages
//config:	are also logged to the system console. Enable this option if you
//config:	wish to enable the 'dmesg' utility.
//config:
//config:config FEATURE_DMESG_PRETTY
//config:	bool "Pretty output"
//config:	default y
//config:	depends on DMESG
//config:	help
//config:	If you wish to scrub the syslog level from the output, say 'Y' here.
//config:	The syslog level is a string prefixed to every line with the form
//config:	"<#>".
//config:
//config:	With this option you will see:
//config:		# dmesg
//config:		Linux version 2.6.17.4 .....
//config:		BIOS-provided physical RAM map:
//config:		 BIOS-e820: 0000000000000000 - 000000000009f000 (usable)
//config:
//config:	Without this option you will see:
//config:		# dmesg
//config:		<5>Linux version 2.6.17.4 .....
//config:		<6>BIOS-provided physical RAM map:
//config:		<6> BIOS-e820: 0000000000000000 - 000000000009f000 (usable)

//applet:IF_DMESG(APPLET(dmesg, BB_DIR_BIN, BB_SUID_DROP))

//kbuild:lib-$(CONFIG_DMESG) += dmesg.o

//usage:#define dmesg_trivial_usage
//usage:       "[-c] [-n LEVEL] [-s SIZE]"
//usage:#define dmesg_full_usage "\n\n"
//usage:       "Print or control the kernel ring buffer\n"
//usage:     "\n	-c		Clear ring buffer after printing"
//usage:     "\n	-n LEVEL	Set console logging level"
//usage:     "\n	-s SIZE		Buffer size"
//usage:     "\n	-r		Print raw message buffer"

#include <sys/klog.h>
#include "libbb.h"

int dmesg_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int dmesg_main(int argc UNUSED_PARAM, char **argv)
{
	int len, level;
	char *buf;
	unsigned opts;
	enum {
		OPT_c = 1 << 0,
		OPT_s = 1 << 1,
		OPT_n = 1 << 2,
		OPT_r = 1 << 3
	};

	opts = getopt32(argv, "cs:+n:+r", &len, &level);
	if (opts & OPT_n) {
		if (klogctl(8, NULL, (long) level))
			bb_simple_perror_msg_and_die("klogctl");
		return EXIT_SUCCESS;
	}

	if (!(opts & OPT_s))
		len = klogctl(10, NULL, 0); /* read ring buffer size */
	if (len < 16*1024)
		len = 16*1024;
	if (len > 16*1024*1024)
		len = 16*1024*1024;

	buf = xmalloc(len);
	len = klogctl(3 + (opts & OPT_c), buf, len); /* read ring buffer */
	if (len < 0)
		bb_simple_perror_msg_and_die("klogctl");
	if (len == 0)
		return EXIT_SUCCESS;


	if (ENABLE_FEATURE_DMESG_PRETTY && !(opts & OPT_r)) {
		int last = '\n';
		int in = 0;

		/* Skip <[0-9]+> at the start of lines */
		while (1) {
			if (last == '\n' && buf[in] == '<') {
				while (buf[in++] != '>' && in < len)
					;
			} else {
				last = buf[in++];
				putchar(last);
			}
			if (in >= len)
				break;
		}
		/* Make sure we end with a newline */
		if (last != '\n')
			bb_putchar('\n');
	} else {
		full_write(STDOUT_FILENO, buf, len);
		if (buf[len-1] != '\n')
			bb_putchar('\n');
	}

	if (ENABLE_FEATURE_CLEAN_UP) free(buf);

	return EXIT_SUCCESS;
}
#define EXTERNALLY_VISIBLE __attribute__(( visibility("default") ))
#define MAIN_EXTERNALLY_VISIBLE EXTERNALLY_VISIBLE

`EXTERNALLY_VISIBLE` 是一个宏定义,用于通过 `__attribute__((visibility("default")))`
属性将声明的符号设置为外部可见。

`__attribute__((visibility("default")))` 是 GNU C 编译器的语法扩展,可以用于指定符号
的可见性。可见性标记是用于控制符号在链接阶段的可见性,即决定符号是否能够被其他目标文件或
动态链接库访问。

通常情况下,默认可见性会被应用于所有的符号。然而,如果我们想将符号标记为外部可见(即在其他
目标文件或动态链接库中可用),就需要使用 `__attribute__((visibility("default")))` 属性
来指定这一可见性。

在这个宏定义中,`EXTERNALLY_VISIBLE` 用于将一个声明设置为外部可见,这意味着其他源文件或
程序可以访问该声明。这样做的一个常见原因是要提供一个公共的接口,使得其他模块或库可以使用它
。在使用这个宏定义时,通常会将它与函数、变量或类型声明一起使用,如下所示:

EXTERNALLY_VISIBLE int my_function();
EXTERNALLY_VISIBLE extern int my_variable;


这样一来,通过 `EXTERNALLY_VISIBLE` 宏定义,这些声明就会被设置为外部可见,可以在其他源文
件或程序中使用和访问。

对于符号的可见性,有几个不同的级别,其中包括 default(默认),hidden(隐藏),protected
(受保护)和 internal(内部)等。

default(默认)可见性是指符号在链接过程中会被默认导出,可以被其他目标文件或动态链接库访问
。这是最常见的可见性级别。

hidden(隐藏)可见性是指符号在链接过程中不会被导出,只能在定义它的目标文件内部使用。其他
目标文件或动态链接库无法直接访问该符号。

protected(受保护)可见性介于 default 和 hidden 之间,在某些情况下限制了符号的可见性,
但又允许共享库之间的访问。

internal(内部)可见性是 GNU C 扩展中的一个特殊级别,用于指定符号只能在同一编译单元内
可见。这意味着该符号只能在定义它的源文件内部使用。

klogctl 函数(来源于 man 手册)

klogctl 函数用于控制内核消息日志,头文件为 #include <sys/klog.h>。它有以下原型:

int syslog(int type, char *bufp, int len);/* No wrapper provided in glibc */
int klogctl(int type, char *buf, int len);
  • type:指定要执行的操作类型。它可以是以下值之一:
类型参数确定此函数所执行的操作。下面的列表指定了类型的值。符号名称在内核源代码中定义,但不
导出到用户空间;您要么使用数字,或者自己实现宏定义。

SYSLOG_ACTION_CLOSE (0)
	Close the log.  Currently a NOP.

SYSLOG_ACTION_OPEN (1)
	Open the log.  Currently a NOP.

SYSLOG_ACTION_READ (2)
	从日志中读取。该调用等待,直到内核日志缓冲区为非空,然后将最多len字节读取到bufp指向的
缓冲区中。该调用返回读取的字节数。从日志中读取的字节从日志缓冲区中消失:信息只能读取一次。
这是当用户程序读取/proc/kmsg时内核执行的函数。
	
SYSLOG_ACTION_READ_ALL (3)
	读取环形缓冲区中剩余的所有消息,将它们放在bufp指向的缓冲区中。该调用从日志缓冲区读取
最后一个len字节(非破坏性),但读取的字节数不会超过自上次“清除环形缓冲区”命令以来写入缓冲
区的字节数(请参阅下面的命令5)。该调用返回读取的字节数
		
SYSLOG_ACTION_READ_CLEAR (4)
	读取并清除环形缓冲区中剩余的所有消息。该调用与类型为3的调用完全相同,但也执行“清除环
形缓冲区”命令。

SYSLOG_ACTION_CLEAR (5)
	该调用仅执行“清除环形缓冲区”命令。bufp和len参数将被忽略。此命令并不能真正清除环形
缓冲区。相反,它设置了一个内核记账变量,用于确定命令3(SYSLOG_ACTION_READ_ALL)和 4
(SYSLOG_ACTION_READ _CLEAR)返回的结果。此命令对命令2(SYSLOG_ACTION_READ)和 9
(SYSLOG_ACTION_SIZE_UNREAD)没有影响。

SYSLOG_ACTION_CONSOLE_OFF (6)
	该命令保存console_loglevel的当前值,然后将console_log级别设置为
minimum_console_lowlevel,这样就不会向控制台打印任何消息。在Linux 2.6.32之前,该命令
只需将console_loglevel设置为minimum_console_longlevel。请参阅下面
对/proc/sys/kernel/printk的讨论。bufp和len参数将被忽略。

SYSLOG_ACTION_CONSOLE_ON (7)
	如果执行了以前的SYSLOG_ACTION_CONSOLE_OFF命令,则此命令会将CONSOLE_loglevel恢复
为该命令保存的值。在Linux 2.6.32之前,此命令只需将console_loglevel设置为
default_console_loglevel。请参阅下面对/proc/sys/kernel/printk的讨论。bufp和len参数
将被忽略。

SYSLOG_ACTION_CONSOLE_LEVEL (8)
	该调用将console_loglevel设置为len中给定的值,该值必须是介于1和8之间(包括1和8)的
整数。内核静默地强制len的最小值minimum_console_loglevel。有关详细信息,请参阅日志级别
部分。bufp参数被忽略。

SYSLOG_ACTION_SIZE_UNREAD (9) (since Linux 2.4.10)
	该调用返回当前可通过命令2(SYSLOG_ACTION_READ)从内核日志缓冲区读取的字节数。bufp
和len参数将被忽略。

SYSLOG_ACTION_SIZE_BUFFER (10) (since Linux 2.6.6)
	此命令返回内核日志缓冲区的总大小。bufp和len参数将被忽略。

	除3和10之外的所有命令都需要特权。在2.6.37之前的Linux内核中,命令类型3和10被允许用于
非特权进程;自Linux以来2.6.37,只有当/proc/sys/kernel/dmesg_restrict的值为0时,才允许
无特权进程使用这些命令。在Linux 2.6.37之前,“特权”意味着呼叫者具有CAP_SYS_ADMIN能力。
从Linux 2.6.37开始,“privileged”表示调用者具有CAP_SYS_ADMIN功能(现在已弃用)或(新的)
CAP_SYSLOG功能。
  • buf:用于读取或写入内核日志的缓冲区。
  • len:长度。

  klogctl 函数允许您控制内核消息日志的操作,例如打开或关闭日志记录,读取最近的日志消息或将消息写入日志中。您可以使用相关的 type 值执行不同的操作,并通过 buf 参数进行数据的读取或写入。需要注意的是,klogctl 函数仅在 Linux 系统中可用,且需要以管理员权限运行。

  /proc/sys/kernel/printk:

	/proc/sys/kernel/printk是一个可写文件,包含四个整数值,这些整数值在打印或记录错误
消息时会影响内核printk()的行为。这四个值是:

console_loglevel
	只有日志级别低于此值的消息才会打印到控制台。该字段的默认值为default_CONSOLE_LOGLEVEL
(7),但如果内核命令行包含单词“quiet”,则将其设置为4;如果内核命令行将包含单词“debug”,
则设置为10;如果出现内核故障,则设置至15(10和15只是愚蠢的,相当于8)。console_loglevel
的值可以通过类型为8的syslog()调用设置(设置为1–8范围内的值)。

default_message_loglevel
	此值将用作没有显式级别的printk()消息的日志级别。在Linux 2.6.38之前(包括该版本),
该字段的硬编码默认值为4(KERN_WARNING);自Linux 2.6.39以来,默认值是由内核配置选项
CON-FIG_default_MESSAGE_LOGLEVEL定义的,默认值为4。

minimum_console_loglevel
	此字段中的值是可以设置console_loglevel的最小值。

default_console_loglevel
	这是console_loglevel的默认值。

内核日志的打印级别:
       Kernel constant   Level value   Meaning
       KERN_EMERG             0        System is unusable
       KERN_ALERT             1        Action must be taken immediately
       KERN_CRIT              2        Critical conditions,关键/临界条件
       KERN_ERR               3        Error conditions
       KERN_WARNING           4        Warning conditions
       KERN_NOTICE            5        Normal but significant condition
       KERN_INFO              6        Informational
       KERN_DEBUG             7        Debug-level messages
返回值
	对于调用为2、3或4的类型,成功调用syslog()将返回读取的字节数。对于类型9,syslog()
返回当前可在内核日志缓冲区上读取的字节数。对于类型10,syslog()返回内核日志缓冲区的总大
小。对于其他类型的值,成功时返回0。
	如果出现错误,则返回-1,并设置errno以指示错误。

错误码
	EINVAL:错误的参数(例如,错误的类型;或对于类型2、3或4,buf为NULL,或len小于零;
或者对于类型8,级别在1到8).

	ENOSYS:此syslog()系统调用不可用,因为编译内核时禁用了CONFIG_PRINTK内核配置选项。

	EPERM:没有足够权限的进程试图更改console_loglevel或清除内核消息环形缓冲区(更准确地
说:没有CAP_SYS_ADMIN或CAP_SYSLOG能力)。

	ERESTARTSYS:系统调用被信号中断;什么也没读。(这只能在跟踪过程中看到)

4、扩展阅读

  linux日志:syslogd和klogd及syslog

二、 /proc/sys/kernel/printk_xxx

  这些是 Linux 内核的一些控制文件,用于配置内核日志和打印设置。下面是对这些文件的详细解释:

  1. /proc/sys/kernel/printk

    • 该文件用于控制内核日志的打印级别。它包含四个整数值(以空格分隔),分别表示控制台日志级别、默认控制台日志级别、启动日志级别和当前日志级别。
  2. /proc/sys/kernel/printk_devkmsg

    • 如果该文件的值为非零,则内核日志将通过/dev/kmsg设备输出。如果为零,则内核日志将不会输出到该设备。默认情况下,它的值为非零。
  3. /proc/sys/kernel/printk_delay

    • 该文件用于设置内核日志的打印延迟时间(以毫秒为单位)。这个延迟时间用于合并相邻的日志消息,以减少日志输出的开销。
  4. /proc/sys/kernel/printk_ratelimit

    • 该文件用于设置内核日志输出的限速,即每秒打印的消息数量限制。默认情况下,它的值为 5
  5. /proc/sys/kernel/printk_ratelimit_burst

    • 该文件用于设置内核日志限速突发打印的数量。当达到限速后,内核可以突发打印多少条日志消息。默认情况下,它的值等于 10 * printk_ratelimit

  这些文件的值可以通过读取和写入这些文件来进行配置。例如,要更改内核日志的打印级别,可以使用以下命令:

echo "<console_loglevel> <default_console_loglevel> <boot_loglevel> <current_loglevel>" > /proc/sys/kernel/printk

  其中,每个<loglevel>代表一个整数,表示对应的日志级别。需要注意的是,对这些控制文件的更改只对当前会话有效,重新启动系统后会恢复为默认值。如果您希望在系统启动时保持更改的值,可以在启动脚本中设置这些文件的值。

三、/dev/kmsg

  /dev/kmsg 是 Linux 操作系统中的一个特殊设备文件,用于读取内核日志。它在内核中用于与用户空间的程序进行通信,并提供了对内核消息缓冲区的访问。

  通过读取 /dev/kmsg,您可以获取内核在运行时生成的各种日志消息,包括内核启动消息、驱动程序消息、错误消息等。这对于诊断系统问题、调试内核模块或了解系统运行状况非常有用。

  为了访问 /dev/kmsg,您可以使用标准的读取文件的方法,例如使用 open 函数打开设备文件,然后使用 read 函数读取其中的数据。示例代码如下:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

#define BUF_SIZE 1024

int main()
{
    int fd = open("/dev/kmsg", O_RDONLY);
    if (fd == -1)
    {
        perror("Failed to open /dev/kmsg");
        return 1;
    }

    char buffer[BUF_SIZE];
    ssize_t bytesRead;

    while ((bytesRead = read(fd, buffer, BUF_SIZE - 1)) > 0)
    {
        buffer[bytesRead] = '\0';
        printf("%s", buffer);
    }

    close(fd);

    return 0;
}

  上述代码将打开 /dev/kmsg,然后使用一个循环不断读取内核日志信息,将其打印到标准输出上直至读取完毕。请注意,读取 /dev/kmsg 通常需要 root 权限或者使用 sudo 运行程序。

  需要注意的是,读取 /dev/kmsg 的方式是阻塞的,也就是说,如果没有新的消息,读取操作将会一直阻塞,直到有新的消息到达。因此,该方式通常用于长期运行或守护进程,以便可以实时监控内核日志。

  summary/proc/kmsg 是一个虚拟文件,/dev/kmsg 是一个设备文件,也用于读取内核日志消息。/proc 下的虚拟文件主要用于提供内核状态和动态信息,而 /dev 下的设备文件主要用于与硬件设备进行交互。

  欢迎大家指导和交流!如果我有任何错误或遗漏,请立即指正,我愿意学习改进。期待与大家一起进步!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言经典算法之希尔排序算法

目录 前言 一、代码实现 二、算法的时空复杂度 时间复杂度&#xff1a; 空间复杂度&#xff1a; 前言 建议&#xff1a;1.学习算法最重要的是理解算法的每一步&#xff0c;而不是记住算法。 2.建议读者学习算法的时候&#xff0c;自己手动一步一步地运行算法。 tips:本算…

prometheus常用exporter

一、node-exporter node_exporter&#xff1a;用于监控Linux系统的指标采集器。 未在k8s集群内的linux机器监控 GitHub - prometheus/node_exporter: Exporter for machine metrics 常用指标&#xff1a; •CPU • 内存 • 硬盘 • 网络流量 • 文件描述符 • 系统负载 •…

黑马程序员 Java设计模式学习笔记(一)

目录 一、设计模式概述 1.1、23种设计模式有哪些&#xff1f; 1.2、软件设计模式的概念 1.3、学习设计模式的必要性 1.4、设计模式分类 二、UML图 2.1、类图概述 2.2、类图的作用 2.3、类图表示法 类的表示方式 类与类之间关系的表示方式 关联关系 聚合关系 组合…

记录汇川:H5U于Factory IO测试13

主程序&#xff1a; 子程序&#xff1a; IO映射 子程序&#xff1a; 辅助出料 子程序&#xff1a; 模式选择 子程序&#xff1a; 示教程序 子程序&#xff1a; 手动程序 子程序&#xff1a; 统计程序 子程序&#xff1a; 异常报警 子程序&#xff1a; 自动程序&#xff1a; F…

PXIe‑6378国产替代,16路AI(16位,3.5 MS/s/ch),4路AO,48路DIO,PXI多功能I/O模块

PXIe&#xff0c;16路AI&#xff08;16位&#xff0c;3.5 MS/s/ch&#xff09;&#xff0c;4路AO&#xff0c;48路DIO&#xff0c;PXI多功能I/O模块 PXIe‑6378是一款同步采样的多功能DAQ设备。 该模块提供了模拟 I/O、数字I/O、四个32位计数器和模拟和数字触发。 板载NI‑STC3…

SIC单晶衬底的常用检测技术

碳化硅&#xff08;SiC&#xff09;作为第三代半导体材料&#xff0c;因其宽禁带宽度、高击穿电场强度和高热导率等优异性能&#xff0c;在众多高端应用领域表现出色&#xff0c;已成为半导体材料技术的重要发展方向之一。SiC衬底分为导电型和半绝缘型两种&#xff0c;各自适用…

c++ 开发生态环境、工作流程、生命周期-拾遗

拾遗 1 生态环境初识 当您使用Visual Studio 2019进行C开发时&#xff0c;您将进入C生态环境。以下是一些重要的概念和步骤&#xff1a; C程序的结构&#xff1a; 一个典型的C程序包括源文件&#xff08;.cpp&#xff09;、头文件&#xff08;.h&#xff09;、编译后的目标文…

javacv和opencv对图文视频编辑-裸眼3D图片制作

通过斗鸡眼&#xff0c;将左右两张相似的图片叠加到一起看&#xff0c;就会有3D效果。 3D图片&#xff0c;3D眼镜&#xff0c;3D视频等原理类似&#xff0c;都是通过两眼视觉差引起脑补产生3D效果。 图片&#xff1a; 图片来源&#xff1a; 一些我拍摄的真*裸眼3D照片 - 哔哩…

LeetCode-1523/1491/860/976

1.在区间范围内统计奇数数目&#xff08;1523&#xff09; 题目描述&#xff1a; 给你两个非负整数 low 和 high 。请你返回 low 和 high 之间&#xff08;包括二者&#xff09;奇数的数目。 思路一&#xff1a; 这里肯定会想到以low和high分别为上下限&#xff0c;然后遍历…

JS实现网页轮播图

轮播图也称为焦点图&#xff0c;是网页中比较常见的网页特效。 1、页面基本结构&#xff1a; 大盒子focus&#xff0c;里面包含 左右按钮ul 包含很多个li &#xff08;每个li里面包含了图片&#xff09;下面有很多个小圆圈 因为我们想要点击按钮&#xff0c;轮播图左右播放&a…

MCU最小系统原理图中四个问题详解——芯片中有很多电源管脚的原因(VDD/VSS/VBAT)、LC滤波、两级滤波、NC可切换元件

前言&#xff1a;本文对MCU最小系统原理图中的四个问题进行详解&#xff1a;芯片中有很多电源管脚的原因&#xff08;VDD/VSS/VBAT&#xff09;、LC滤波、两级滤波、NC可切换元件。本文以GD32F103C8T6最小系统原理图举例 目录&#xff1a; 芯片中有很多电源管脚的原因&#x…

ssh远程登录

ssh协议 ---基于 tcp 的 22 号端口 确认是否有ssh包&#xff1a; [rootserver ~] rpm -qa | grep sshopenssh-clients-8.7p1-24.el9_1.x86_64openssh-server-8.7p1-24.el9_1.x86_64 1、 ssh的验证过程 第一阶段&#xff1a;版本协商以及tcp三次握手 第二阶段&#xff1a;秘钥和…

WebServer 跑通/运行/测试(详解版)

&#x1f442; 椿 - 沈以诚 - 单曲 - 网易云音乐 目录 &#x1f382;前言 &#x1f33c;跑通 &#xff08;1&#xff09;系统环境 &#xff08;2&#xff09;克隆源码 &#xff08;3&#xff09;安装和配置 Mysql &#xff08;4&#xff09;写 sql 语句 &#xff08;5&…

LeetCode114二叉树展开为链表(相关话题:后序遍历)

题目描述 给你二叉树的根结点 root &#xff0c;请你将它展开为一个单链表&#xff1a; 展开后的单链表应该同样使用 TreeNode &#xff0c;其中 right 子指针指向链表中下一个结点&#xff0c;而左子指针始终为 null 。展开后的单链表应该与二叉树 先序遍历 顺序相同。 示例…

LabVIEW通过视频识别开发布氏硬度机自动化测量系统

LabVIEW通过视频识别开发布氏硬度机自动化测量系统 概述&#xff1a; 在当前的工业检测与自动化领域&#xff0c;对于精确测量技术的需求日益增长。特别是在材料硬度测试领域&#xff0c;布氏硬度机的自动化测量出现在越来越多的使用中。展示了一个基于LabVIEW开发的布氏硬度…

工业异常检测AnomalyGPT-训练试跑及问题解决

写在前面&#xff0c;AnomalyGPT训练试跑遇到的坑大部分好解决&#xff0c;只有在保存模型失败的地方卡了一天才解决&#xff0c;本来是个小问题&#xff0c;昨天没解决的时候尝试放弃在单卡的4090上训练&#xff0c;但换一台机器又遇到了新的问题&#xff0c;最后决定还是回来…

详谈Python的开发工具

Python作为一种流行的编程语言&#xff0c;在开发过程中需要使用各种工具来提高效率、简化工作流程和改善开发体验。在本文中&#xff0c;我们将介绍一些常用的Python开发工具&#xff0c;包括文本编辑器、集成开发环境&#xff08;IDE&#xff09;、虚拟环境管理工具、包管理器…

【数据结构与算法】之数组系列-20240113

这里写目录标题 一、66. 加一二、121. 买卖股票的最佳时机三、136. 只出现一次的数字四、268. 丢失的数字五、350. 两个数组的交集 II 一、66. 加一 简单 给定一个由 整数 组成的 非空 数组所表示的非负整数&#xff0c;在该数的基础上加一。 最高位数字存放在数组的首位&…

这可能是最全面的Java集合面试八股文了

内容摘自我的学习网站&#xff1a;topjavaer.cn 常见的集合有哪些&#xff1f; Java集合类主要由两个接口Collection和Map派生出来的&#xff0c;Collection有三个子接口&#xff1a;List、Set、Queue。 Java集合框架图如下&#xff1a; List代表了有序可重复集合&#xff0c…

第 10 章 树结构的基础部分

文章目录 10.1 二叉树10.1.1 为什么需要树这种数据结构10.1.2 树示意图10.1.3 二叉树的概念10.1.4 二叉树遍历的说明10.1.5 二叉树遍历应用实例(前序,中序,后序)10.1.6 二叉树-查找指定节点10.1.7 二叉树-删除节点10.1.8 二叉树-删除节点 10.2 顺序存储二叉树10.2.1 顺序存储二…