透过 /proc 看见内核:Linux 虚拟文件系统与 systemd 初始化初探

news2025/5/16 2:33:10

当我们在终端中输入 pstopcat /proc/cpuinfo 等命令时,是否思考过这些信息来自哪里?为什么无需启动任何守护进程,就能实时读取系统负载、内存占用,甚至内核版本?这一切的答案,都藏在 Linux 系统中的一个目录——/proc/proc 是 Linux 提供的一个虚拟文件系统(procfs),它不占用实际磁盘空间,而是由内核在内存中动态生成的。这个特殊的文件系统为用户空间提供了观察和控制内核状态的窗口,贯穿系统生命周期的方方面面。

尤其值得注意的是 /proc/1/,它代表系统中第一个用户空间进程 systemd。理解这个目录背后的机制,不仅能揭示 Linux 系统的初始化流程,还能帮助我们理解容器隔离、性能调优、安全监控等关键场景。本文将从 /proc 的结构与用途出发,结合 systemd 的初始化机制,逐步解析虚拟文件系统的内核实现原理,以及它在现代 Linux 中的意义。

一.深入 /proc:内核与进程信息的大本营

/proc 虚拟文件系统的根目录下,既包含大量以数字命名的子目录,也包含一些代表系统运行状态的特殊文件。这些内容可以分为两大类:

在这里插入图片描述

1.进程相关目录(/proc/[pid]/

系统中每一个正在运行的进程,都会在 /proc 下有一个以其进程号(PID)命名的目录,比如 /proc/1//proc/1123/ 等。这个目录中的文件反映了该进程的实时状态,例如:

文件/目录说明
cmdline启动命令及其参数
cwd当前工作目录(符号链接)
exe可执行程序路径(符号链接)
status人类可读的进程状态信息
stat更详细的进程状态,ps 命令依赖此文件
fd/文件描述符目录,列出该进程打开的所有文件
maps内存映射信息(代码段、数据段、共享库等)
stack内核栈的回溯信息(用于调试)

通过这些文件,我们可以轻松监控、调试和分析系统中任意一个进程。例如:

cat /proc/$$/cmdline     # 查看当前 shell 的启动命令
ls -l /proc/1/fd         # 查看 PID 1 打开的文件描述符
cat /proc/1/status       # 查看 systemd 的进程状态信息

2.系统级别信息文件

除了进程目录,/proc 根目录还包含许多关键系统信息,例如:

文件/目录内容
cpuinfoCPU 型号、核数、频率等
meminfo内存使用情况
uptime系统启动至今的时长
loadavg系统负载情况
modules已加载的内核模块
version内核版本号
stat系统级统计信息(进程数、CPU 使用等)
mounts / mountinfo当前挂载的文件系统
filesystems支持的文件系统类型

3.动态内核参数接口:/proc/sys/

这一目录下的内容对应内核的可调参数,通过它我们可以动态修改内核行为,如网络设置、内存策略、进程限制等:

cat /proc/sys/net/ipv4/ip_forward        # 查看 IP 转发是否开启
echo 1 > /proc/sys/net/ipv4/ip_forward   # 启用 IP 转发

二、/proc/1:揭开第一个用户进程 systemd 的面纱

在 Linux 系统启动完成后,用户空间的第一个进程总是拥有一个固定的 PID —— 1。它通常是我们熟悉的 systemd,也是整个用户空间中最重要的“总管”。

1.systemd 是怎么启动的?

整个系统的启动过程大致如下:

[BIOS/UEFI][GRUB 等引导加载器][Linux 内核加载][init进程启动]

当内核完成自身初始化后,它会尝试执行第一个用户空间进程,通常的查找顺序为:

  1. 内核启动参数中的 init= 指定的路径(如 init=/bin/sh
  2. /sbin/init
  3. /etc/init
  4. /bin/init
  5. /bin/sh

而在现代 Linux 系统中,这个 “init” 通常是 /lib/systemd/systemd 的软链接,或者直接是 /sbin/init 指向 systemd

可以通过如下命令验证:

ls -l /sbin/init
lrwxrwxrwx 1 root root 20 1122  2023 /sbin/init -> /lib/systemd/systemd

所以,当看到 /proc/1/ 时,这个目录下的信息正对应着 systemd 的运行状态。

2.观察 /proc/1/ —— 进程 systemd 的现场

我们可以进入 /proc/1/,查看这个特殊进程的启动方式:

 tr '\0' ' ' < /proc/1/cmdline
/sbin/init auto noprompt splash

这是进程 1(systemd)的命令行启动参数:

  • /sbin/init:可执行程序路径
  • autonopromptsplash:传递给 init 的启动参数

这说明内核启动后,通过如下方式执行了第一个进程:

execve("/sbin/init", ["/sbin/init", "auto", "noprompt", "splash"], envp);

那内核是“怎么”启动这个 /sbin/init 的?

当 Linux 内核完成自身初始化后,它会在 init/main.c 中尝试执行第一个用户空间进程(以下内核源码来自6.12 init/main.c):

if (execute_command) {
    ret = run_init_process(execute_command);
    if (!ret)
        return 0;
    panic("Requested init %s failed (error %d).", execute_command, ret);
}

如果内核启动参数中传入了 init=xxx,那么它优先尝试执行这个指定的路径,否则继续尝试默认路径:

if (CONFIG_DEFAULT_INIT[0] != '\0') {
    ret = run_init_process(CONFIG_DEFAULT_INIT);
    ...
}

这是编译内核时指定的默认 init 路径,通常不会设置。然后进入备选方案:

if (!try_to_run_init_process("/sbin/init") ||
    !try_to_run_init_process("/etc/init") ||
    !try_to_run_init_process("/bin/init") ||
    !try_to_run_init_process("/bin/sh"))
    return 0;

内核尝试从多个默认路径中依次查找有效的 init 进程,这就是我们看到 /sbin/init 的来源。

3./lib/systemd/systemd 到底是什么

这个目录里是 systemd 的主程序 —— 一个ELF 可执行文件,由 systemd 项目编译生成,功能非常强大,是整个用户空间初始化和服务管理的核心。

可以直接用 file 命令查看它的本质:

file /lib/systemd/systemd
/lib/systemd/systemd: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=2ab06decf08c9378367b98f3e592473ea32a5b3c, for GNU/Linux 3.2.0, stripped

这表明它是一个编译好的 64 位 ELF 可执行文件,能被内核通过 execve() 调用执行。

我们可以使用objdump去反编译 systemd:

objdump -x /lib/systemd/systemd

/lib/systemd/systemd:     文件格式 elf64-x86-64
/lib/systemd/systemd
体系结构:i386:x86-64, 标志 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
起始地址 0x0000000000042690

程序头:
    PHDR off    0x0000000000000040 vaddr 0x0000000000000040 paddr 0x0000000000000040 align 2**3
         filesz 0x00000000000002d8 memsz 0x00000000000002d8 flags r--
  INTERP off    0x0000000000000318 vaddr 0x0000000000000318 paddr 0x0000000000000318 align 2**0
         filesz 0x000000000000001c memsz 0x000000000000001c flags r--
    LOAD off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**12
         filesz 0x0000000000035af8 memsz 0x0000000000035af8 flags r--
    LOAD off    0x0000000000036000 vaddr 0x0000000000036000 paddr 0x0000000000036000 align 2**12
         filesz 0x00000000000df58d memsz 0x00000000000df58d flags r-x
    LOAD off    0x0000000000116000 vaddr 0x0000000000116000 paddr 0x0000000000116000 align 2**12
         filesz 0x000000000005ea10 memsz 0x000000000005ea10 flags r--
    LOAD off    0x0000000000174e90 vaddr 0x0000000000175e90 paddr 0x0000000000175e90 align 2**12
         filesz 0x000000000004e28c memsz 0x00000000000505b0 flags rw-
 DYNAMIC off    0x00000000001c0780 vaddr 0x00000000001c1780 paddr 0x00000000001c1780 align 2**3
         filesz 0x0000000000000280 memsz 0x0000000000000280 flags rw-
    NOTE off    0x0000000000000338 vaddr 0x0000000000000338 paddr 0x0000000000000338 align 2**3
         filesz 0x0000000000000030 memsz 0x0000000000000030 flags r--
    NOTE off    0x0000000000000368 vaddr 0x0000000000000368 paddr 0x0000000000000368 align 2**2
         filesz 0x0000000000000044 memsz 0x0000000000000044 flags r--
0x6474e553 off    0x0000000000000338 vaddr 0x0000000000000338 paddr 0x0000000000000338 align 2**3
         filesz 0x0000000000000030 memsz 0x0000000000000030 flags r--
EH_FRAME off    0x00000000001572f0 vaddr 0x00000000001572f0 paddr 0x00000000001572f0 align 2**2
         filesz 0x0000000000002dc4 memsz 0x0000000000002dc4 flags r--
   STACK off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4
         filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
   RELRO off    0x0000000000174e90 vaddr 0x0000000000175e90 paddr 0x0000000000175e90 align 2**0
         filesz 0x000000000004e170 memsz 0x000000000004e170 flags r--

动态节:
  NEEDED               libsystemd-shared-249.so
  NEEDED               libseccomp.so.2
  NEEDED               libselinux.so.1
  NEEDED               libmount.so.1
  NEEDED               libpam.so.0
  NEEDED               libaudit.so.1
  NEEDED               libkmod.so.2
  NEEDED               libapparmor.so.1
  NEEDED               libc.so.6
  RUNPATH              /lib/systemd
  INIT                 0x0000000000036000
  FINI                 0x0000000000115580
  INIT_ARRAY           0x0000000000175e90
  INIT_ARRAYSZ         0x0000000000000008
  FINI_ARRAY           0x0000000000175e98
  FINI_ARRAYSZ         0x0000000000000008
  GNU_HASH             0x00000000000003b0
  STRTAB               0x0000000000007ac0
  SYMTAB               0x00000000000004a0
  STRSZ                0x0000000000005c20
  SYMENT               0x0000000000000018
  DEBUG                0x0000000000000000
  PLTGOT               0x00000000001c1a00
  PLTRELSZ             0x0000000000006d08
  PLTREL               0x0000000000000007
  JMPREL               0x000000000002edf0
  RELA                 0x000000000000e2b8
  RELASZ               0x0000000000020b38
  RELAENT              0x0000000000000018
  FLAGS                0x0000000000000008
  FLAGS_1              0x0000000008000001
  VERNEED              0x000000000000e0b8
  VERNEEDNUM           0x0000000000000007
  VERSYM               0x000000000000d6e0
  RELACOUNT            0x0000000000001346

版本引用:
  required from libapparmor.so.1:
    0x06236661 0x00 24 APPARMOR_1.1
    0x02363623 0x00 20 APPARMOR_2.13
    0x02363620 0x00 16 APPARMOR_2.10
  required from libmount.so.1:
    0x03a775e9 0x00 17 MOUNT_2.19
    0x03a775f0 0x00 12 MOUNT_2.20
    0x03a775f6 0x00 10 MOUNT_2.26
  required from libpam.so.0:
    0x04682f60 0x00 09 LIBPAM_1.0
  required from libselinux.so.1:
    0x0edb87f0 0x00 06 LIBSELINUX_1.0
  required from libkmod.so.2:
    0x07026af5 0x00 05 LIBKMOD_5
  required from libsystemd-shared-249.so:
    0x047c3134 0x00 04 SD_SHARED
  required from libc.so.6:
    0x06969188 0x00 26 GLIBC_2.28
    0x06969186 0x00 25 GLIBC_2.26
    0x0d696918 0x00 23 GLIBC_2.8
    0x09691973 0x00 22 GLIBC_2.3.3
    0x06969197 0x00 21 GLIBC_2.17
    0x06969194 0x00 19 GLIBC_2.14
    0x0d696919 0x00 18 GLIBC_2.9
    0x069691b4 0x00 15 GLIBC_2.34
    0x06969190 0x00 14 GLIBC_2.10
    0x0d696914 0x00 13 GLIBC_2.4
    0x06969185 0x00 11 GLIBC_2.25
    0x069691b3 0x00 08 GLIBC_2.33
    0x0d696917 0x00 07 GLIBC_2.7
    0x09691a75 0x00 03 GLIBC_2.2.5
    0x09691974 0x00 02 GLIBC_2.3.4

节:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .interp       0000001c  0000000000000318  0000000000000318  00000318  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .note.gnu.property 00000030  0000000000000338  0000000000000338  00000338  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .note.gnu.build-id 00000024  0000000000000368  0000000000000368  00000368  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .note.ABI-tag 00000020  000000000000038c  000000000000038c  0000038c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .gnu.hash     000000ec  00000000000003b0  00000000000003b0  000003b0  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .dynsym       00007620  00000000000004a0  00000000000004a0  000004a0  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .dynstr       00005c20  0000000000007ac0  0000000000007ac0  00007ac0  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .gnu.version  000009d8  000000000000d6e0  000000000000d6e0  0000d6e0  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  8 .gnu.version_r 00000200  000000000000e0b8  000000000000e0b8  0000e0b8  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  9 .rela.dyn     00020b38  000000000000e2b8  000000000000e2b8  0000e2b8  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 10 .rela.plt     00006d08  000000000002edf0  000000000002edf0  0002edf0  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 11 .init         0000001b  0000000000036000  0000000000036000  00036000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 12 .plt          000048c0  0000000000036020  0000000000036020  00036020  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 13 .plt.got      00000050  000000000003a8e0  000000000003a8e0  0003a8e0  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 14 .plt.sec      000048b0  000000000003a930  000000000003a930  0003a930  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 15 .text         000d639f  000000000003f1e0  000000000003f1e0  0003f1e0  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 16 .fini         0000000d  0000000000115580  0000000000115580  00115580  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 17 .rodata       000412f0  0000000000116000  0000000000116000  00116000  2**5
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 18 .eh_frame_hdr 00002dc4  00000000001572f0  00000000001572f0  001572f0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 19 .eh_frame     0001a958  000000000015a0b8  000000000015a0b8  0015a0b8  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 20 .init_array   00000008  0000000000175e90  0000000000175e90  00174e90  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 21 .fini_array   00000008  0000000000175e98  0000000000175e98  00174e98  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 22 .data.rel.ro  0004b8e0  0000000000175ea0  0000000000175ea0  00174ea0  2**5
                  CONTENTS, ALLOC, LOAD, DATA
 23 .dynamic      00000280  00000000001c1780  00000000001c1780  001c0780  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 24 .got          000025f8  00000000001c1a00  00000000001c1a00  001c0a00  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 25 .data         0000011c  00000000001c4000  00000000001c4000  001c3000  2**5
                  CONTENTS, ALLOC, LOAD, DATA
 26 .bss          00002320  00000000001c4120  00000000001c4120  001c311c  2**5
                  ALLOC
 27 .gnu_debugaltlink 00000047  0000000000000000  0000000000000000  001c311c  2**0
                  CONTENTS, READONLY
 28 .gnu_debuglink 00000034  0000000000000000  0000000000000000  001c3164  2**2
                  CONTENTS, READONLY
SYMBOL TABLE:
无符号

我们用 objdump 工具分析 /lib/systemd/systemd 这个 systemd 主程序后可以看到,它是一个结构完整的 ELF 动态链接可执行文件:

  • 它的入口地址由内核调用,是整个用户空间的启动点
  • 它依赖大量核心系统库,如 libselinux、libpam、libmount、libaudit 等
  • 它通过动态链接器 /lib64/ld-linux-x86-64.so.2 加载运行所需库
  • 它的各个段区(.text、.data、.init_array、.got、.plt 等)清晰地定义了 systemd 的功能划分

这说明 systemd 不是一个单纯的“init 工具”,而是连接 Linux 内核与用户空间生态的核心组件。它的结构复杂而严谨,是现代操作系统服务调度的基础。

三、/proc 的内核实现原理

在前面我们看到,/proc 并不是一个普通的文件系统,它里面的文件不会真正存储在磁盘上,而是内核在内存中实时生成的。这种文件系统被称为 虚拟文件系统(Virtual File System),而 /proc 正是 Linux 中最早的虚拟文件系统之一。

那这些文件是如何实现的?我们又是如何通过 cat /proc/cpuinfo 获取到 CPU 信息的呢?

1. procfs 是如何挂载到 /proc 的?

在 Linux 启动的早期阶段,内核会主动调用 proc_root_init() 来初始化 proc 文件系统,并将其挂载到 /proc 目录下:

proc_root_init();           // 初始化 procfs 根目录
mount("proc", "/proc", "proc", 0, NULL);  // 挂载 proc 文件系统

2. 文件内容是怎么来的?——动态生成!

与普通文件不同,/proc 下的文件在访问时才会动态生成内容,不占用任何磁盘空间。以 /proc/cpuinfo 为例:

  • 当你执行 cat /proc/cpuinfo
  • 内核会调用绑定到这个路径上的 show_cpuinfo() 函数
  • 函数读取内核中的 CPU 数据结构(如 cpu_data[]
  • 然后格式化内容返回给用户空间

这依赖于 proc_create()proc_create_single() 这些内核 API:

proc_create("cpuinfo", 0444, NULL, &cpuinfo_proc_ops);

&cpuinfo_proc_ops 是一组 file_operations 函数指针(如 .read.open 等),当你执行 cat 时,就会调用 read() 指针对应的函数来生成输出内容。

3. /proc/[pid]/ 的文件又是怎么实现的?

这部分更有趣 —— 每当有新进程创建时,内核会在 /proc 下创建一个以 PID 为名的目录,并挂载一组与该进程有关的动态文件。这些内容来自于内核中的 task_struct 结构体,它是内核维护的每个进程的核心信息块。

  • /proc/[pid]/status 对应的是当前进程的 task_struct 中各种状态字段
  • /proc/[pid]/fd/ 是根据该进程的文件描述符数组生成的
  • /proc/[pid]/maps 是进程地址空间的内存映射

也就是说,你在 /proc/1234/status 中看到的内容,其实是内核将 task_struct 中的信息格式化后,通过 seq_fileproc_ops 机制动态生成的。

4. /proc/sys/ 与内核参数(sysctl)的关系

/proc/sys/ 是另一个特殊子系统,它与 sysctl 机制联动,允许我们动态修改内核参数

例如:

echo 1 > /proc/sys/net/ipv4/ip_forward

等价于:

sysctl -w net.ipv4.ip_forward=1

这些路径在内核中通过 register_sysctl() 机制注册,并绑定到对应的内核变量上。例如 ip_forward 就是一个内核布尔变量,写入它实际上会影响内核行为。

四、/proc 与容器隔离

在现代 Linux 容器技术(如 Docker、Kubernetes)中,Namespace 是实现隔离的基础,而 /proc 是最直观体现这种隔离的接口之一。

容器通常使用 PID namespace 进行进程号隔离。每个容器中都会挂载一个独立的 /proc,看起来它的 PID 是从 1 开始的,但这只是当前命名空间的视角。

# 宿主机中
ps -ef | grep my-container-process
# PID = 12345

# 容器内
ps -ef
# PID = 1(看不到宿主机其他进程)

这时容器内的 /proc 实际上是一个挂载在 proc namespace 视角下的虚拟视图。

/proc/[pid]/ 中的信息是基于当前命名空间 task_struct 中的映射生成的。/proc/self/ 永远指向当前进程/proc/[pid]/,即使是容器内。这让容器内的用户空间感知不到外部系统,增强安全性和资源控制能力。

总结

通过这篇文章,我们从 /proc 的结构出发,一步步深入了解了它如何连接用户空间与内核空间:

  • /proc/[pid]/ 是每个进程实时的状态镜像,提供了强大的观察与调试能力;
  • /proc/1/ 揭示了 systemd 的诞生过程,以及内核如何启动第一个用户空间进程;
  • /lib/systemd/systemd 本质上是一个功能强大的 ELF 可执行程序,承担整个系统初始化和服务调度任务;
  • /proc 文件系统并非来自磁盘,而是由内核动态生成,与 task_structsysctl 等内核数据结构紧密耦合;
  • 在容器中,/proc 则体现出 Namespace 隔离的魔力,是进程、资源和安全视图隔离的核心接口。

可以说,/proc 不仅是系统调试与监控的重要接口,更是理解 Linux 内核工作方式的重要切入点。它像一面镜子,映照出正在运行的内核机制;也像一扇窗,让我们窥见内核深处的世界。

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

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

相关文章

用DrissionPage升级维基百科爬虫:更简洁高效的数据抓取方案

一、原方案痛点分析 原代码使用urllibBeautifulSoup组合存在以下问题&#xff1a; 动态内容缺失&#xff1a;无法获取JavaScript渲染后的页面内容 反爬能力弱&#xff1a;基础请求头易被识别为爬虫 代码冗余&#xff1a;需要单独处理SSL证书验证 扩展性差&#xff1a;难以应…

C++STL——容器-vector(含部分模拟实现,即地层实现原理)(含迭代器失效问题)

目录 容器——vector 1.构造 模拟实现 2.迭代器 模拟实现&#xff1a; ​编辑 3.容量 模拟实现&#xff1a; 4.元素的访问 模拟实现 5.元素的增删查改 迭代器失效问题&#xff1a; 思考问题 【注】&#xff1a;这里的模拟实现所写的参数以及返回值&#xff0c;都是…

严重BUG修复及部分体验问题优化

随着Deepseek APIPython 测试用例一键生成与导出 V1.0.6的试用不断深入&#xff0c;会出现程序异常崩溃的问题。经群友定位&#xff0c;紧急修复了bug&#xff0c;并适当优化部分体验性问题。针对生成的测试用例xlsx文档&#xff0c;可以再次选中该xlsx给大模型进行推理生成新的…

Elasticsearch 证书问题解决

报错信息 javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested targetat org.elasticsearch.client.RestClient. extractAndWrapCause(R…

2023年CIE SCI1区TOP:序列融合麻雀搜索算法ISSA,深度解析+性能实测

目录 1.摘要2.麻雀搜索算法SSA原理3.改进策略3.结果展示4.参考文献5.代码获取 1.摘要 麻雀搜索算法&#xff08;SSA&#xff09;是一种基于麻雀觅食和防捕行为的群体智能算法。然而&#xff0c;基本SSA在迭代过程中&#xff0c;种群多样性逐渐降低&#xff0c;容易陷入局部最优…

配置晟腾910b的PyTorch torch_npu环境

1.【新教程】华为昇腾NPU的pytorch环境搭建 - Lukea - 博客园 1、新建conda环境。 conda create -n pytorch python3.102、在新建好的conda环境中&#xff0c;安装基础的依赖。 pip install attrs cython numpy1.24.0 decorator sympy cffi pyyaml pathlib2 psutil protobuf…

conda 激活环境vscode的Bash窗口

多份conda环境注意事项&#xff0c;当时安装了两个conda环境&#xff0c;miniconda和conda&#xff0c;导致环境总是冲突矛盾。初始化时需要更加注意。 $ C:/Users/a_hal/miniconda3/Scripts/conda.exe init bash能够显示用哪里的conda环境命令执行。 然后直接conda activate…

火山 RTC 引擎 2 ----APPKEY

前篇文章&#xff1a;火山RTC引擎 --一次失望的体验 那个DEMO可以编译运行了&#xff0c;但是功能不能用&#xff0c; 一用就崩溃。 主要原因还是没有APPKEY 一、火山引擎 APPKEY 管理 1、登录后台 账号登录-火山引擎欢迎登录火山引擎&#xff0c;火山引擎是字节跳动旗下的云…

Springboot学习笔记3.28

目录 实战第六课&#xff1a;文章分类开发 新增文章分类&#xff1a; 具体实现&#xff1a; 查询文章分类&#xff1a; 具体实现&#xff1a; 获取文章分类的详情 更新文章分类&#xff1a; 注意点&#xff1a; ​编辑 对校验规则进行分组&#xff1a; 学习时的疑惑…

【CSS3】05-定位 + 修饰属性

本文介绍定位和CSS中的修饰属性。 目录 1. 定位 1.1 相对定位 1.2 绝对定位 1.3 定位居中 1.4 固定定位 1.5 z-index堆叠层级 2. 修饰属性 2.1 垂直对齐方式 vertical-align 2.2 过渡属性 2.3 透明度 opacity 2.4 光标类型 cursor 1. 定位 灵活改变盒子在网页中的位…

如何屏蔽mac电脑更新提醒,禁止系统更新

最烦mac的系统更新提醒了&#xff0c;过几天就是更新弹窗提醒&#xff0c;现在可以直接禁掉了&#xff0c;眼不见心不乱&#xff0c;不然一升级&#xff0c;开发环境全都不能用了&#xff0c;那才是最可怕的&#xff0c;屏蔽的方法也很简单&#xff0c;就是屏蔽mac系统更新的请…

Rclone同步Linux数据到google云盘

文章目录 Rclone管理云存储Rclone安装和使用说明安装rclone配置rclone连接到云盘基本备份命令高级备份选项自动化备份加密备份&#xff08;可选&#xff09;恢复数据常见云存储服务名称注意事项 googleCloud 平台中操作OAuth权限请求页面&#xff08;OAuth同意屏幕&#xff09;…

AI人工智能-Jupyter NotbookPycharm:Py开发

安装 命令&#xff1a; pip install jupyter 启动 命令&#xff1a; jupyter notebook 启动成功后&#xff0c;下面网址会默认自动打开当前用户的根目录。 其实这个页面显示的内容&#xff0c;是我们电脑目录C:\Users\当前用户\下的文件夹 我们平常做实验&#xff0c;希望在…

DDR简介

一、什么是DDR&#xff1f; DDR SDRAM&#xff08;Double Data Rate Synchronous DYNAMIC RAM&#xff09;中文名是&#xff1a;双倍数据速率同步动态随机存储器。 传统的SDRAM只在时钟信号的上升沿传输数据&#xff0c;而DDR可以同时在时钟的上升沿和下降沿传输数据&#xf…

VRRP(虚拟路由器冗余协议)、虚拟路由器、master路由器、backup路由器

VRRP(虚拟路由器冗余协议) 1、介绍 虚拟路由冗余协议 VRRP (Virtual Router Redundancy Protocol)通过把几台路由设备联合组成一台虚拟的路由设备&#xff0c;将虚拟路由设备的IP地址作为用户的默认网关实现与外部网络通信。当网关设备发生故障时&#xff0c;VRRP机制能够选举…

多模态RAG实践:如何高效对齐不同模态的Embedding空间?

目录 多模态RAG实践&#xff1a;如何高效对齐不同模态的Embedding空间&#xff1f; 一、为什么需要对齐Embedding空间&#xff1f; 二、常见的对齐方法与关键技术点 &#xff08;一&#xff09;对比学习&#xff08;Contrastive Learning&#xff09; &#xff08;二&#…

vue中的 拖拽

拖拽总结 实现方式特点适用场景HTML5 原生拖拽 API✅ 直接使用 dataTransfer 进行数据传输 ✅ 兼容性好&#xff08;大部分浏览器支持&#xff09; ✅ 适合简单的拖拽场景低代码平台、表单生成器、组件拖拽Vue/React 组件库&#xff08;如 Vue Draggable、SortableJS&#xff…

Linux进程间通信(1)

1.IPC 1.什么是IPC&#xff1f; Inter Process Communication 2.进程间通信常用的几种方式 1&#xff0c;管道通信&#xff1a;有名管道&#xff0c;无名管道 2&#xff0c;信号- 系统开销小 3&#xff0c;消息队列-内核的链表 4&#xff0c;信号量-计数器 5&#xff0c;共享…

Scala相关知识学习总结3

包 - 包声明&#xff1a;和Java类似&#xff0c;作用是区分同名类、管理类命名空间。Scala包名只能含数字、字母等&#xff0c;不能数字开头、不能用关键字。 - 包说明&#xff1a;有类似Java的包管理风格&#xff0c;也有独特嵌套风格。嵌套风格有两个特点&#xff0c;一是&…

Opencv计算机视觉编程攻略-第七节 提取直线、轮廓和区域

第七节 提取直线、轮廓和区域 1.用Canny 算子检测图像轮廓2.用霍夫变换检测直线&#xff1b;3.点集的直线拟合4.提取连续区域5.计算区域的形状描述子 图像的边缘区域勾画出了图像含有重要的视觉信息。正因如此&#xff0c;边缘可应用于目标识别等领域。但是简单的二值边缘分布图…