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

[OS_8] 终端和 UNIX Shell | 会话和进程组 | sigaction | dash

  • 我们已经知道如何用 “文件描述符” 相关的系统调用访问操作系统中的对象:open, read, write, lseek, close。
  • 操作系统也提供了 mount, pipe, mkfifo 这些系统调用能 “创建” 操作系统中的对象。

当然,我们也知道操作系统中的对象远不止于此,还有很多有趣的对象我们还没有深入了解过——终端就让人细思恐极。

本文内容:从我们每天用的终端模拟器开始,一探究竟 Ctrl-C 到底做了什么——在此基础上,我们就可以实现自己的 “多任务管理器” 了。

8.1 终端

打字机 (Typewriter)

QWERTY 键盘 (1860s)

  • 为降低打字速度设计的防卡纸方案
    • 毕竟机械结构,每一下都需要足够的力量

打字机时代的遗产

Shift

  • 使字锤或字模向上移动一段距离,切换字符集

CR & LF

  • \r CR (Carriage Return): 回车,将打印头移回行首
    • print('Hel\rlo')
  • \n LF (Line Feed): 换行,将纸张向上移动一行
    • UNIX 的 \n 同时包含 CR 和 LF

Tab & Backspace

  • 位置移动 (Backspace + 减号 = 错了划掉)

电传打字机 (Teletypewriter)

为了发电报设计 (收发两端同时打印)

  • Telex (teleprinter exchange): 1920s,早于计算机
    • 使用 Baudot Code (5-bit code)
    • 很自然地也能用在计算机上
    • 应用场景:早期股票同步交易

电传打字机 (cont'd)

  • Teletype Model 28 (1951); technical data sheet

VT100: 封神之路

Video Teletypewriter(视频电传打字机) (DEC, 1978)

  • 成为事实上的行业标准
    • 首个完整实现 ANSI Escape Sequence 的终端
    • 80×2480×24 字符显示成为标准布局

计算机终端:原理

输出设备(比如屏幕)

想象你对着对讲机念一串咒语:"变红#大家好#恢复颜色"。虽然你听到的是乱码,但对讲机那头的人听到后会立刻把文字变成红色显示"大家好",再恢复颜色。
这里的UART信号就像咒语,Escape Sequence(例如\033[31m)就是告诉屏幕何时变色、换行的魔法指令。

输入设备(比如键盘)

你按键盘的"回车键",键盘不会大喊"回车",而是悄悄告诉电脑一个暗号(比如ASCII码13)。电脑听到暗号后,就知道该执行回车操作了。
控制字符(如换行符、退格符)就是这些约定好的"暗号系统"

一对 “管道” 提供双向通信通道

  • 主设备 (PTY Master): 连接到终端模拟器
  • 从设备 (PTY Slave): 连接到 shell 或其他程序
    • 例如 /dev/pts/0

在 Linux 系统中,tty(Teletype 的缩写)是一个与终端交互相关的核心概念,本质上是终端设备的抽象表示

伪终端经常被创建

  • ssh, tmux new-window, ctrl-alt-t, ...
  • openpty(): 通过 /dev/ptmx 申请一个新终端
    • 返回两个文件描述符 (master/slave)
    • (感受到 “操作系统对象” 的恐怖体量了吧)

终端打开接口

  • xterm.js vscode 三端 兼容的实现

终端模拟器 (Terminal Emulator)

这下你也会实现了

  • openpty + fork
    • 子进程:stdin/stdout/stderr 指向 slave 文件
    • 父进程:从 master 读取输出显示到屏幕; 将键盘输入写入 master 文件

甚至可以扩展 Escape Sequence 来显示图片

  • Kitty: \033[60C\_ 开头,\033\ 结尾
    • 允许控制大小、位置、动画等
    • kitten icat img.png | cat
  • 应该内嵌 WebView 的 期待这个革命性的产品

终端:更多功能

终端模式

  • Canonical Mode: 按行处理
    • 回车发送数据 (终端提供行编辑功能)
  • Non-canonical Mode: 按字符处理
    • 每个字符立即发送给程序
    • 用于实现交互式程序: vim, ssh sshtron.zachlatta.com

终端属性控制

  • tcgetattr/tcsetattr (terminal control)
  • 可以控制终端的各种行为:回显、信号处理、特殊字符等
    • (你输密码的时候关闭了终端的回显)

8.2 终端和操作系统

程序是怎么和终端 “配对” 的?

用户登录的起点

  • 系统启动 (内核 → init → getty)
  • 远程登录 (sshd → fork → openpty)
    • stdin, stdout, stderr 都会指向分配的终端
  • vscode (fork → openpty)

login 程序继承分配的终端

  • (是的,login 是一个程序)
  • fork() 会继承文件描述符 (指针)
    • 因此,子进程也会指向同一个终端

终于,我们有了足够的机制实现 “用户界面”

  • 终端是一个人机交互的东西

当然,不是图形的

UNIX Shell: “终端” 时代的经典设计

  • “Command-line interface” (CLI) 的巅峰

进程管理:要解决的问题

我们有那么大一棵进程树,都指向同一个终端,有的在前台,有的在后台,Ctrl-C 到底终止哪个进程?

答案:终端才不管呢

  • 它只管传输字符
    • Ctrl-C: End of Text (ETX), \x03
    • Ctrl-D: End of Transmission (EOT), \x04
    • stty -a: 你可以看到按键绑定 (奇怪的知识增加了)

  • 操作系统收到了这个字符
    • 就可以对 “当前” 的进程采取行动

ctrl+z 实现 切换为后台

作为操作系统的设计者,需要在收到 Ctrl-C 的时候找到一个 “当前进程”

你会怎么做?

  • fork() 会产生树状结构
    • (还有托孤行为)
  • Ctrl-C 应该终止所有前台的 “进程们”
    • 但不能误伤后台的 “进程们”

shell 终端知道前后台,但是操作系统怎么知道前后台呢?

会话 (Session) 和进程组 (Process Group)

给进程引入一个额外编号 (Session ID,大分组)

  • 子进程会继承父进程的 Session ID
    • 一个 Session 关联一个控制终端 (controlling terminal)
    • Leader 退出时,全体进程收到 Hang Up (SIGHUP)

再引入另一个编号 (Process Group ID,小分组)

  • 一个会话 只能有一个前台进程组
  • 操作系统收到 Ctrl-C,向前台进程组所有进程发送 SIGINT
    • (真累……但你也想不到更好的设计了)

会话组 vs 进程组 —— 为什么分开?

想象一个 公司部门(会话组) 里有很多 项目小组(进程组)

  1. 分工明确
    • 部门负责整体事务(比如与总部对接、分配办公电脑)
    • 小组专注具体任务(比如开发、测试)
      *👉 终端需要会话组管理登录、设备权限;进程组专注执行具体命令(如 ls | grep txt)*
  1. 灵活调整
    • 部门可以合并或拆分(例如关闭终端时,自动结束所有关联进程)
    • 小组可以独立运作(例如 Ctrl+Z 暂停一个进程组,不影响其他小组)
      *👉 分开后,信号(如 Ctrl+C)可以精准发送到指定进程组*

为什么只有一个前台进程组?

想象 超市收银台(终端) 的规则:

  1. 避免混乱
    • 同一时间只能有一个顾客(前台进程组)在结账
    • 其他顾客(后台进程组)需要排队等待
      *👉 终端输入(键盘、信号)同一时刻只能交给一个进程组处理*
  1. 快速切换
    • 你正在结账(前台),突然电话响了,可以暂停当前操作去接电话(切换到新前台进程组)
      *👉 用 fg/bg 命令切换进程组的前后台状态*

实际场景例子

假设你在终端运行:

$ sleep 100 | sleep 200 &  # 后台进程组
$ vi file.txt              # 前台进程组
  • Ctrl+C 会杀死 vi(前台进程组),而不会影响后台的 sleep
  • 关闭终端时,会话组会向所有进程组发送终止信号

总结:分层设计让管理更精细,就像公司需要部门和小组的分工协作。


会话和进程组:API

太不优雅了

  • setsid/getsid
    • setsid 会脱离 controlling terminal
  • setpgid/getpgid
  • tcsetpgrp/tcgetpgrp
    • 迷惑 API

以及……uid, effective uid (?), saved uid (???)

  • 任何软件都很难逃脱千疮百孔的设计
  • 一些解决:Setuid Demystified


  • 对于很多接口我们只能增加很难删减

终于能实现 Job Control 了

窗口和多任务:终端可以有 “一个前台进程组”

  • “最小化” = Ctrl-Z (SIGTSTP)
    • SIGTSTP 默认行为暂停进程,收到 SIGCONT 后恢复
  • “切换” = fg/bg (tcsetpgrp)

为了实现 “窗口栏上的按钮”,还很是大费周章

  • 还不如 tmux 管理多个 pty 呢 (选择性 “绘制” 在终端上)
    • 那是因为发明 session/pg 的时候还没有 pty 呢……


是的,历史的糟粕

但是,这是 POSIX 的一部分……

  • 几乎任何人都无法预知 “软件” 的未来

回头看这个问题

  • 我们不需要 “绑定进程到设备”
  • 管理程序 (tmux, gnome, ...) 去模拟就行
    • Window Manager: 只需要 “进程组” 就行了
      • 关窗口,全部 一个不留
    • Android: 每个 app 都是不同的用户
      • 强行终止 = 杀掉属于这个用户的所有进程
    • Snap: 程序在隔离的沙箱运行
      • AppArmor + seccomp + namespaces (真狠)

不同操作系统(Unix-like vs. Windows)的设计理念差异

比喻:公司管理模式对比

  • Unix-like(会话+进程组)
    像一家强调 精细分工 的科技公司:
    • 每个部门(会话)负责一个独立业务线(如终端登录、后台服务)
    • 部门内有多个项目组(进程组),比如开发组、测试组、运维组
    • 前台项目组(前台进程组)才能直接对接客户(终端输入/输出)
  • Windows(仅进程组)
    像一家强调 统一管理 的传统企业:
    • 所有员工(进程)都属于公司(系统)直接管理
    • 通过工牌权限(安全标识符 SID)和部门标签(Job Object)区分职责
    • 没有严格的“前台项目组”概念,所有窗口(进程)均可交互

为什么 Windows 可以“没有会话”?
  1. 设计目标不同
    • Windows 早期注重 单用户图形交互,进程天然与桌面绑定
    • Unix 源自 多用户命令行 场景,需要会话管理终端(如 SSH 登录)
  1. 替代机制
    • 窗口站(Window Station):隔离不同安全级别的进程(类似会话)
    • 服务控制管理器(SCM):管理后台服务(类似守护进程与会话解绑)
    • Job Object:将多个进程绑定为组,统一管理资源(CPU/内存限制)
  1. 用户场景差异
    • Windows 服务程序通常不与终端关联,无需会话控制输入输出
    • Unix 的 ssh/tmux/screen 等工具严重依赖会话的终端绑定能力

会话的核心作用(以 Unix 为例)

  1. 终端绑定
    • 会话与一个终端(如 SSH 连接、物理控制台)关联
    • 只有前台进程组能接收终端输入(如键盘信号)
  1. 信号管理
    • Ctrl+C 仅杀死前台进程组,而非整个会话
    • 关闭终端时,会话向所有进程组广播 SIGHUP(默认终止进程)
  1. 资源隔离
    • 会话退出时自动释放终端设备、共享内存等资源
    • Windows 通过对象句柄继承和 Job Object 实现类似功能

实际案例对比

  • Unix 场景
    你在 SSH 会话中运行:
$ python server.py &  # 后台进程组
$ vim file.txt        # 前台进程组
    • 按下 Ctrl+C 仅终止 vimpython 继续运行
    • 断开 SSH 后,会话销毁,python 进程收到 SIGHUP 终止
  • Windows 场景
    你打开两个命令行窗口:
    • 窗口1运行 notepad.exe(普通进程组)
    • 窗口2运行 powershell.exe(另一个进程组)
    • 关闭窗口1不会影响窗口2,因为无会话绑定

为什么需要会话?

  1. 精细控制:对进程组的生命周期、信号、终端交互实现分层管理
  2. 多用户支持:隔离不同登录用户(或终端连接)的资源
  3. 作业控制fg/bgjobs 等命令依赖会话的前后台机制

Windows 并非“不需要会话”,而是通过 窗口站/Job Object/SCM 等机制实现了类似功能

但抽象层级和实现方式不同。就像公司管理模式没有绝对优劣,只有适合场景的区别。


在未来回头看现在

人机交互的方式根本不应该是这样的

  • 我们很少能清醒地认识到
    • 我要做 X
    • 应该分解成 Y→(Z,W)→T
  • 因此,坐在电脑前的大部分时间都浪费了

Prompt: 在有了 pty 机制之后,我们可以用 session 的机制,为每个 “窗口” 分配一个新的 pty,这样可以简化系统调用,例如 process group 的概念可以消除。是否可以这样设计新的操作系统?

理论上,这种设计是可行的,但需要谨慎权衡利弊:

1. 可行性分析

  • PTY与会话的1:1绑定确实能简化部分终端管理逻辑
  • 进程组原有的作业控制功能(如信号广播、终端抢占)可被会话继承
  • 现代容器化趋势下,会话级的资源隔离更符合最小化原则

2. 潜在优势

  • 减少进程组/会话组ID的维护开销
  • 窗口崩溃时可通过会话机制自动回收资源
  • 更清晰的层次结构:终端→会话→进程树

3. 关键挑战

  • POSIX兼容性问题:许多程序依赖setsid()/tcsetpgrp()等系统调用
  • 精细控制需求:某些场景仍需进程组级别的信号传递
  • 内核调度影响:会话级cgroup可能比进程组更重量级

4. 折中建议

  • 保留进程组作为可选机制
  • 在用户空间抽象会话管理(如systemd-style)
  • 通过命名空间隔离, 增强会话安全性

这种设计在嵌入式/专用系统中有应用前景,但通用系统需保持向后兼容。当前Linux的cgroups v2已部分实现类似理念,通过进程树替代进程组管理资源。


最后:Ctrl-C 到底做了什么?

signal

  • 注册一个信号的 “处理程序” f
    • 操作系统会记下这个 f

kill

  • 在程序从操作系统返回时,强制加一个向 ff 的跳转
    • 程序 = 状态机
    • 只要 “模拟” 调用 ff 的行为即可

今天有更可靠的版本 (sigaction)

  • 让 AI 解释 一下吧

Prompt: 为什么我们需要 sigaction 替代 UNIX 的信号机制?

使用 sigaction 替代传统的 UNIX signal 机制,主要出于以下原因:

1. 行为可靠性

  • 传统 signal 的缺陷:早期 signal 函数在信号处理完成后,自动将信号处理程序重置为默认行为(如 SIG_DFL),需要手动重新注册,易导致信号丢失或竞态条件。
  • sigaction 改进:通过 SA_RESTART 标志支持系统调用自动重启,避免因信号中断导致的系统调用意外终止,提升程序健壮性。

2. 精确控制信号行为

  • 屏蔽信号sigaction 允许在信号处理期间,通过 sa_mask 字段阻塞特定信号,防止嵌套信号干扰,确保处理逻辑的原子性。
  • 上下文信息:通过 siginfo_t 结构体可获取信号的来源信息(如发送进程 PID、错误地址等),增强调试能力。

3. 可移植性

  • 传统 signal 函数在不同 UNIX 系统中的实现不一致(如 BSD 和 System V)。sigaction 是 POSIX 标准化的接口,提供统一行为,避免跨平台兼容性问题。

4. 避免信号丢失

  • sigactionSA_NODEFERSA_RESETHAND 标志允许更灵活控制信号递送,避免传统机制中因信号处理重置导致的多次信号丢失。

示例对比

// 传统 signal 的脆弱实现
void handler(int sig) {signal(SIGINT, handler);  // 必须手动重新注册// 处理逻辑
}
signal(SIGINT, handler);// 使用 sigaction 的可靠实现
struct sigaction sa;
sa.sa_handler = handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;  // 自动重启系统调用
sigaction(SIGINT, &sa, NULL);

总结

sigaction 通过提供原子性注册阻塞控制上下文信息标准化行为,解决了传统 signal 的不可靠性和平台依赖问题,是现代 UNIX 系统编程中推荐使用的信号处理机制。


8.3 UNIX Shell 编程语言

“多任务” 不是人机交互的全部

Windows 3.2 (1992): “多窗口管理器” 并不那么好用


The Shell Programming Language

UNIX 的用户可都是 hackers

  • UNIX Shell: 基于文本替换的极简编程语言
    • 只有一种类型:字符串
    • 算术运算?对不起,我们不支持 (但可以 expr 1 + 2)

语言机制

  • 预处理: $(), <()
  • 重定向: cmd > file < file 2> /dev/null
  • 顺序结构: cmd1; cmd2, cmd1 && cmd2, cmd1 || cmd2
  • 管道: cmd1 | cmd2
    • 这些命令被翻译成系统调用序列 (open, dup, pipe, fork, execve, waitpid, ...)

例子:实现重定向

利用子进程继承文件描述符的特性

  • 在父进程打开好文件,到子进程里腾挪
    • 发现还是 Windows API 更 “优雅”
int fd_in  = open(..., O_RDONLY | O_CLOEXEC);
int fd_out = open(..., O_WRONLY | O_CLOEXEC);int pid = fork();
if (pid == 0) {dup2(fd_in, 0);dup2(fd_out, 1);execve(...);
} else {close(fd_in);close(fd_out);waitpid(pid, &status, 0);
}

读一读手册 (为数不多还值得读的手册)

man sh: dash — command interpreter (shell)

  • dash is the standard command interpreter for the system. The current version of dash is in the process of being changed to conform with the POSIX 1003.2 and 1003.2a specifications for the shell.
  • The shell is a command that reads lines from either a file or the terminal, interprets them, and generally executes other commands. It is the program that is running when a user logs into the system (although a user can select a different shell with the chsh(1) command).

我们可以借助 AI 来读

UNIX Shell: 优点

优点:高效、简介、精确

  • 一种 “自然编程语言”:一行命令,协同多个程序
    • make -nB | grep ...
    • 最适合 quick & dirty 的 hackers

AI 时代的 UNIX Philosophy

  • man tcsetpgrp | ag -q 帮我生成新手友好的教程
  • 出了问题还可以 fxxk

UNIX Shell: 有优点就有缺点

无奈的取舍

  • Shell 的设计被 “1970s 的算力、算法和工程能力” 束缚了
    • 后人只好将错就错 (PowerShell: 我好用,但没人用 )
    • PowerShell 了解一下,面向对象的管道
    • 因为市场上的人们已经习惯了shell,这告诉我们宣传和抢占市场也很重要

例子:操作的 “优先级”?

  • ls > a.txt | cat
    • 我已经重定向给 a.txt 了,cat 是不是就收不到输入了?
  • bash/zsh 的行为是不同的
    • 所以脚本用 #!/bin/bash 甚至 #!/bin/sh 保持兼容
  • 文本数据 “责任自负”
    • 空格 = 灾难

另一个有趣的例子

$ echo hello > /etc/a.txt
bash: /etc/a.txt: Permission denied$ sudo echo hello > /etc/a.txt

A Zero-dependency UNIX Shell

真正体现 “Shell 是 Kernel 之外的 壳”

  • 来自 xv6
  • 完全基于系统调用 API,零库函数依赖
    • -ffreestanding 编译、ld 链接

支持的功能

  • 重定向/管道 ls > a.txt, ls | wc -l
  • 后台执行 ls &
  • 命令组合 (echo a ; echo b) | wc -l

展望未来

Open question

  • Shell (CLI/GUI) 的未来是什么

一些想法

  • 是一个 “半结构化” 的 “编程语言”
    • project files | filter out generated files | zip them
    • make a slides of UNIX shell | play it
    • 我们就可以退休啦

8.4 总结

Take-away Messages:

通过 freestanding 的 shell,我们阐释了 “可以在系统调用上创建整个操作系统应用世界” 的真正含义:操作系统的 API 和应用程序是互相成就、螺旋生长的:有了新的应用需求,就有了新的操作系统功能。

而 UNIX 为我们提供了一个非常精简、稳定的接口 (fork, execve, exit, pipe ,...),纵然有沉重的历史负担,它在今天依然工作得很好。

相关文章:

[OS_8] 终端和 UNIX Shell | 会话和进程组 | sigaction | dash

我们已经知道如何用 “文件描述符” 相关的系统调用访问操作系统中的对象&#xff1a;open, read, write, lseek, close。操作系统也提供了 mount, pipe, mkfifo 这些系统调用能 “创建” 操作系统中的对象。 当然&#xff0c;我们也知道操作系统中的对象远不止于此&#xff0…...

IP查询专业版:支持IPv4/IPv6自动识别并切换解析的API接口使用指南

以下是根据您提供的网页内容编辑的符合CSDN内容发布要求的Markdown格式文本&#xff1a; 一、API概述 在开发过程中&#xff0c;我们常常需要对IP地址进行查询&#xff0c;以获取其详细信息&#xff0c;如地理位置、运营商等。万维易源的“IP查询专业版”API接口能够提供丰富…...

ESG跨境电商如何为国内的跨境电商企业打开国外的市场

现在不管是国内还是国外&#xff0c;做电商的企业都非常的多&#xff0c;那么既然有这么多大电商公司&#xff0c;就要有为这些电商公司提供服务的公司&#xff0c;这就是ESG&#xff0c;它是专门为跨境电商服务的公司&#xff0c;那么这家公司的主要业务是什么呢&#xff1f;它…...

建筑节能成发展焦点,楼宇自控应用范围持续扩大

在全球能源危机日益严峻、环保意识不断增强的大环境下&#xff0c;建筑节能已成为建筑行业发展的核心议题。从大型商业综合体到普通住宅&#xff0c;从公共建筑到工业厂房&#xff0c;节能需求贯穿建筑全生命周期。而楼宇自控系统凭借其对建筑设备的智能化管理和精准调控能力&a…...

中国矿业大学iGMAS分析中心介绍

一、关于GNSS和iGMAS 在浩瀚的太空中&#xff0c;全球卫星导航系统&#xff08;GNSS&#xff09;构建起精准定位的时空基准。IGMAS——国际GNSS监测评估系统&#xff0c;是由中国倡导并主导建设的全球GNSS监测网络&#xff0c;旨在提供高精度、高可靠的导航、定位与授时服务。 …...

python如何取消word中的缩进

在python-docx中&#xff0c;取消缩进可以通过将相应的缩进属性设置为None或0来实现。以下是取消不同类型缩进的方法&#xff1a; 取消左缩进 from docx import Documentdoc Document(existing_document.docx)for paragraph in doc.paragraphs:# 取消左缩进paragraph.paragr…...

Lesar: 面向 Lustre/Scade 语言的形式化模型检测工具

在《同步反应式系统》的第一课中&#xff0c;介绍了同步数据流语言 Lustre 生态中的形式化模型检查器 Lesar 的用法。Lesar 可对 lustre v4 语言以及 Scade 语言中部分数据流核心特性进行模型检查。 Lesar 介绍 Lesar 是 Verimag 研发维护的形式化方法模型检查工具。该工具的理…...

YOLOv12 改进有效系列目录 - 包含卷积、主干、检测头、注意力机制、Neck上百种创新机制 - 针对多尺度、小目标、遮挡、复杂环境、噪声等问题!

&#x1f525; 在 YOLO 系列一路狂飙之后&#xff0c;YOLOv12 带来了令人耳目一新的范式转变——它不再以 CNN 为绝对核心&#xff0c;而是首次 围绕注意力机制构建 YOLO 框架&#xff0c;在保证实时性的前提下&#xff0c;将检测精度再次推向新高度&#xff01; 为了进一步探…...

STM32 I2C总线通信协议

引言 在嵌入式系统开发领域&#xff0c;I2C&#xff08;Inter-Integrated Circuit&#xff09;总线作为经典的双线制串行通信协议&#xff0c;凭借其简洁的物理层设计和灵活的通信机制&#xff0c;在传感器互联、存储设备控制、显示模块驱动等场景中占据重要地位。本文将深入剖…...

多物理场耦合低温等离子体装置求解器PASSKEy2

文章目录 PASSKEy2简介PASSKEY2计算流程PASSKEy2 中求解的物理方程电路模型等离子体模型燃烧模型 PASSKEy2的使用 PASSKEy2简介 PASSKEy2 是在 PASSKEy1 的基础上重新编写的等离子体数值模拟程序。 相较于 PASSKEy1&#xff0c; PASSKEy2 在具备解决低温等离子体模拟问题的能力…...

【Harmony_Bug】forEach + asyncawait 的异步陷阱

一、问题描述 今天在做一个RDB的小项目时&#xff0c;遇到一个问题&#xff0c;因为没报错其实也是不算是BUG&#xff0c;以下描述时我就直接说关键点&#xff0c;其他代码忽略。 我的数据模型初始化有六条数据如图 在持久化层&#xff0c;通过initUserData这个方法执行插入。…...

智慧医院建设的三大关键领域

智慧医院建设是医疗行业数字化转型的核心载体&#xff0c;其本质是通过新一代信息技术重构医疗服务模式、优化管理流程、提升患者体验。在当前医疗资源供需矛盾突出的背景下&#xff0c;智慧医院建设已从单纯的设备智能化向系统性变革演进&#xff0c;主要集中在以下三大关键领…...

雷电模拟器怎么更改IP地址

游戏搬砖会使用雷电模拟器多开窗口&#xff0c;若模拟器窗口开多了&#xff0c;IP地址是一样的就怕有限制&#xff0c;很容易被游戏后台检测到。在雷电模拟器中更改IP地址可以通过以下方法实现&#xff1a; 方法一&#xff1a;通过模拟器内设置代理 1. 打开雷电模拟器 启动雷…...

软件编程命名规范

编程命名规范是保证代码可读性、可维护性和团队协作效率的重要基础。以下是涵盖主流编程语言的通用命名规范&#xff0c;结合行业最佳实践和常见规范&#xff08;如Google、Microsoft、Airbnb等风格指南&#xff09;&#xff1a; 一、通用命名原则 清晰优先&#xff1a;名称应…...

#什么是爬虫?——从技术原理到现实应用的全面解析 VI

什么是爬虫?——从技术原理到现实应用的全面解析 V 二十六、异构数据采集技术突破 26.1 PDF文本与表格提取 import pdfplumber import pandas as pddef extract_pdf_data(pdf_path):"""从PDF中提取文本和表格数据:param pdf_path: PDF文件路径:return: 包含…...

芯岭技术XL32F003单片机 32位Cortex M0+ MCU简单介绍 性能优异

XL32F003单片机是深圳市芯岭技术有限公司的一款基于 32 位 ARM Cortex-M0 内核的高性能微控制器&#xff0c;提供SOP8/SOP14/SOP16/TSSOP20/SSOP24/QFN20/QFN32多种封装可选&#xff0c;可满足不同设计需求。XL32F003可用于工业控制、手持设备、PC 外设、传感器节点等应用场景&…...

使用浏览器的Clipboard API实现前端复制copy功能

在前端开发中&#xff0c;复制文本到剪贴板的功能通常使用浏览器的 Clipboard API 实现。比如 navigator.clipboard.writeText 方法。以下是一个简单的案例&#xff0c;展示如何使用 Clipboard API 实现复制文本的功能。 基本用法 首先&#xff0c;你需要创建一个按钮&#x…...

Struts2框架学习

文章目录 基础实战配置文件NameSpaces 基础 实战 配置文件 文件1&#xff1a; <?xml version"1.0" encoding"UTF-8"?> // 声明这是一个 XML 文件&#xff0c;且使用 UTF - 8 编码 <!DOCTYPE struts PUBLIC"-//Apache Software Foundat…...

React 实现爱心花园动画

主页&#xff1a; import React, { useEffect, useRef, useState } from react; import /assets/css/Love.less; import { Garden } from /utils/GardenClasses;// 组件属性接口 interface LoveAnimationProps {startDate?: Date; // 可选的开始日期messages?: { // 可…...

CAPL编程_03

1_文件操作的相关函数&#xff1a; 读文本文件内容 读取文本文件操作的三部曲 1&#xff09;打开文件 —— openFileRead ( ) 2&#xff09;逐行读取 —— fileGetString ( ) 、fileGetStringSZ ( ) 3&#xff09;关闭文件 —— fileClose ( ) char content[100];…...

网络准入控制系统:2025年网络安全的坚固防线

在当今数字化时代&#xff0c;网络安全已成为至关重要的议题。阳途网络准入控制系统作为保障网络安全的关键机制&#xff0c;发挥着不可替代的作用。 阳途网络准入控制系统核心目的在于确保只有合法、合规的设备与用户能够接入网络。从本质上讲&#xff0c;它通过一系列技术手段…...

【音视频】⾳频处理基本概念及⾳频重采样

一、重采样 1.1 什么是重采样 所谓的重采样&#xff0c;就是改变⾳频的采样率、sample format、声道数等参数&#xff0c;使之按照我们期望的参数输出。 1.2 为什么要重采样 为什么要重采样? 当然是原有的⾳频参数不满⾜我们的需求&#xff0c;⽐如在FFmpeg解码⾳频的时候…...

自然语言处理将如何颠覆未来教育?个性化学习新纪元

教育领域正经历着自印刷术发明以来最深刻的变革。自然语言处理&#xff08;NLP&#xff09;技术突破传统教育框架的桎梏&#xff0c;正在重塑人类知识传递的基本范式。这场变革的实质不在于教学工具的数字化升级&#xff0c;而在于重新定义了"教"与"学"的本…...

4月25日星期五今日早报简报微语报早读

4月25日星期五&#xff0c;农历三月廿八&#xff0c;早报#微语早读。 1、祝贺&#xff01;神舟二十号载人飞船发射取得圆满成功&#xff1b; 2、文旅部&#xff1a;今年一季度国内出游人次17.94亿&#xff0c;同比增长26.4%&#xff1b; 3、2025五一档新片预售票房破1000万&…...

秒级到毫秒:BFD的速度革命

一、BFD技术概述 ​​双向转发检测&#xff08;BFD&#xff09;​​是一种轻量级的网络协议&#xff0c;专门用于快速检测、监控网络链路或IP路由的连通性状态。作为网络领域的"心跳检测器"&#xff0c;BFD通过毫秒级&#xff08;默认1000ms&#xff09;的快速探测机…...

systemctl 命令详解与常见问题解决

在 Linux 系统中&#xff0c;service 命令和 chkconfig 命令一直用于管理服务&#xff0c;但随着 systemd 的引入&#xff0c;systemctl 命令逐渐成为主流。systemctl 命令不仅功能强大&#xff0c;而且使用简单。本文将详细介绍 systemctl 命令的作用以及常见问题的解决方法。…...

5.6 Microsoft Semantic Kernel:专注于将LLM集成到现有应用中的框架

5.6.1 Semantic Kernel概述 Microsoft Semantic Kernel&#xff08;以下简称SK&#xff09;是一个开源的软件开发工具包&#xff08;SDK&#xff09;&#xff0c;旨在帮助开发者将大型语言模型&#xff08;LLM&#xff09;无缝集成到现有的应用程序中。它支持C#、Python和Java…...

vite+vue构建的网站项目localhost:5173打不开

原因&#xff1a;关掉了cmd命令提示符&#xff0c;那个端口就没有被配置上&#xff0c;打开就是这样的。 解决方法&#xff1a;重新在工作目录下打开cmd&#xff0c;输入npm run dev重新启动项目。 重新出现这样的界面说明已经成功启动项目&#xff0c;再次在浏览器中刷新并输入…...

电脑屏幕录制软件Captura源码编译(Win10,VS2022)

屏幕录像的意义&#xff1a; 教育教学方面 制作教学资源&#xff1a;教师可以通过录制屏幕来制作教学视频&#xff0c;演示软件操作、讲解复杂的知识点等。学生可以随时观看这些视频&#xff0c;便于复习和巩固知识&#xff0c;尤其对于一些抽象的概念或难以在课堂上一次性掌握…...

【版本控制】SVN + TortoiseSVN版本管理实用教程(附安装+开发常用操作)

摘要&#xff1a; 本文将带你从零开始掌握 SVN 版本控制系统&#xff0c;结合 TortoiseSVN 图形客户端工具&#xff0c;深入学习包括安装、检出、提交、更新、回滚、冲突解决等常用开发操作&#xff0c;快速上手团队协作&#xff01; &#x1f9e9; 什么是 SVN&#xff1f; SV…...

常见网络安全攻击类型深度剖析(二):SQL注入攻击——原理、漏洞利用演示与代码加固方法

常见网络安全攻击类型深度剖析(二):SQL注入攻击——原理、漏洞利用演示与代码加固方法 在Web应用安全领域,SQL注入(SQL Injection)是历史最悠久、危害最广泛的攻击类型之一。据OWASP(开放式Web应用安全项目)统计,SQL注入连续多年稳居“OWASP Top 10”漏洞榜单前列,每…...

DeepSeek智能时空数据分析(三):专业级地理数据可视化赏析-《杭州市国土空间总体规划(2021-2035年)》

序言&#xff1a;时空数据分析很有用&#xff0c;但是GIS/时空数据库技术门槛太高 时空数据分析在优化业务运营中至关重要&#xff0c;然而&#xff0c;三大挑战仍制约其发展&#xff1a;技术门槛高&#xff0c;需融合GIS理论、SQL开发与时空数据库等多领域知识&#xff1b;空…...

day49—双指针+贪心—验证回文串(LeetCode-680)

题目描述 给你一个字符串 s&#xff0c;最多 可以从中删除一个字符。 请你判断 s 是否能成为回文字符串&#xff1a;如果能&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a;s "aba" 输出&#xff1a;true…...

AI电视里的达摩

2025年&#xff0c;所有电视都搭载了AI功能&#xff0c;所有电视厂商都在宣传AI能力。但问题是&#xff0c;消费者依旧没有对AI电视做出什么积极的回应。“AI电视是鸡肋”“AI只是电视的又一轮泡沫”等观点层出不穷。 为什么明明AI技术能够解决电视的很多问题&#xff0c;但AI电…...

算力网络(CFN)在跨校联合科研中的应用:安全性挑战与联邦调度实践

引言&#xff1a;科研协作的算力困境 上海交通大学与麻省理工学院联合开展的高能物理模拟实验&#xff0c;因算力资源分配不均导致部分节点连续72小时处于空转状态。这个典型案例揭示了当前跨机构科研协作的痛点&#xff1a;‌算力资源无法实现安全可信的细粒度共享‌。算力网…...

面向对象编程核心:封装、继承、多态与 static 关键字深度解析

面向对象编程核心&#xff1a;封装、继承、多态与 static 关键字深度解析 一、封装&#xff1a;数据安全与接口规范 1. 封装的本质与作用 核心定义&#xff1a;将数据&#xff08;属性&#xff09;与操作数据的方法&#xff08;行为&#xff09;绑定在类中&#xff0c;隐藏内…...

c++进阶——类与继承

文章目录 继承继承的基本概念继承的基本定义继承方式继承的一些注意事项 继承类模板 基类和派生类之间的转换继承中的作用域派生类的默认成员函数默认构造函数拷贝构造赋值重载析构函数默认成员函数总结 不能被继承的类继承和友元继承与静态成员多继承及其菱形继承问题继承模型…...

【CODEMATE】进制转换(transform) 粤港澳青少年信息学创新大赛 C/C++/Python 解题思路

目录 问题描述做题思路&#xff0c;解决过程思路&#xff1a;踩过的坑&#xff1a;核心代码C 语言 / C 切片&#xff1a;C 语言 / C 判断 ‘A’ 数量&#xff1a;Python 切片&#xff1a;Python 判断 ‘A’ 数量&#xff1a; 完整代码C 语言 完整代码C 完整代码Python 完整代码…...

window和ubuntu自签证书

window下 以管理员身份 运行 Windows PowerShell # CN192.168.0.100 (换成自己的IP或者域名) # O(组织) OU(组织单位) # Cert:\LocalMachine\My&#xff1a;证书存储位置 # test_10&#xff1a;自定义证书名称 .AddYears(10): 证书过期时间 10 年 $cert New-SelfSi…...

ES历史版本下载

下载地址 Past Releases of Elastic Stack Software | Elastic 安装步骤参考 windows 安装 Elasticsearch_windows安装elasticsearch-CSDN博客...

技术面试一面标准流程

0. 自我介绍 ...... 1. 拷打项目 项目干了啥&#xff1f; 难点是啥&#xff1f; 问项目中用到的东西&#xff1f; 扩展&#xff1f; ...... 2. 基础知识 数据结构、C基础、设计模式 数据结构&#xff1a; 堆&#xff1f; unordered_map 和 布隆过滤器 都是用于查找…...

第14篇:Linux设备驱动程序入门<一>

Q&#xff1a;如何简单的理解DE1-SoC-UP Linux系统的设备驱动程序&#xff1f; A&#xff1a;设备驱动程序&#xff08;Device Driver&#xff09;&#xff0c;简称驱动程序&#xff08;Driver&#xff09;。DE1-SoC-UP Linux系统中的设备驱动程序允许系统软件与DE1-SoC开发板…...

软件设计模式与体系结构:基于Java实现管道-过滤器架构

软件设计模式与体系结构&#xff1a;基于Java实现管道-过滤器架构 前言 在软件架构中&#xff0c;数据流风格是一种常见的架构模式&#xff0c;特别适用于需要对数据进行一系列处理的场景。管道-过滤器&#xff08;Pipe and Filter&#xff09;*架构是数据流风格的典型代表&a…...

Node.js 包管理工具介绍

Node.js 包管理工具介绍 Node.js 是一个基于 Chrome V8 JavaScript 引擎的服务器端运行环境&#xff0c;它允许开发者使用 JavaScript 进行后端开发。为了方便管理和维护项目中使用的第三方库和模块&#xff0c;Node.js 提供了多种包管理工具。本文将详细介绍几种常用的 Node.…...

Node.js 应用场景

Node.js 应用场景 引言 Node.js 是一个基于 Chrome V8 JavaScript 引擎的开源、跨平台 JavaScript 运行环境。它主要用于服务器端开发&#xff0c;通过非阻塞 I/O 模型实现了高并发处理能力。本文将详细介绍 Node.js 的应用场景&#xff0c;帮助你了解其在实际项目中的应用。…...

C/C++线程详解

一、C语言线程创建&#xff08;POSIX线程&#xff09; 1. 基本创建方法 POSIX线程&#xff08;pthread&#xff09;是C语言中创建线程的标准API&#xff1a; #include <pthread.h> #include <stdio.h>void* thread_func(void* arg) {printf("Thread runnin…...

动态ip与静态ip的概念、区别、应用场景

动态ip与静态ip的区别 前言 一、IP地址的概念和作用 1.1、IP地址的定义 1.2、IP地址的作用 二、动态IP和静态IP的区别 2.1、动态IP和静态IP的定义 2.2、动态IP和静态IP的特点 2.3、动态IP和静态IP的优缺点比较 三、动态IP和静态IP的应用场景 3.1. 动态IP的应用场景 3.2. 静态IP…...

P12167 [蓝桥杯 2025 省 C/Python A] 倒水

P12167 [蓝桥杯 2025 省 C/Python A] 倒水 题目描述 小蓝有 n n n 个装了水的瓶子&#xff0c;从左到右摆放&#xff0c;第 i i i 个瓶子里装有 a i a_i ai​ 单位的水。为了美观&#xff0c;小蓝将水循环染成了 k k k 种颜色&#xff0c;也就是说&#xff0c;第 i i i …...

Appium自动化开发环境搭建

自动化 文章目录 自动化前言 前言 Appium是一款开源工具&#xff0c;用于自动化iOS、Android和Windows桌面平台上的本地、移动web和混合应用程序。原生应用是指那些使用iOS、Android或Windows sdk编写的应用。移动网页应用是通过移动浏览器访问的网页应用(appum支持iOS和Chrom…...

【金仓数据库征文】金仓数据库:国产化浪潮下的技术突破与行业实践

目录 前言 技术突破&#xff1a;从追赶国际到引领创新 行业深耕&#xff1a;从医疗到航空航天的多领域落地 事务管理与ACID特性 事务管理概述 索引优化与性能调优 安全性与备份恢复策略 Json构造函数 总结 前言 在数字化转型的全球趋势下&#xff0c;数据库作为信息系…...