【嵌入式Linux应用开发基础】特殊进程
目录
一、守护进程(Daemon Process)
1.1. 概念
1.2. 特点
1.3. 守护进程的命名
1.4. 创建守护进程的步骤
1.5. 守护进程的实例
1.6. 守护进程的管理
1.7. 影响与处理
二、僵尸进程(Zombie Process)
2.1. 僵尸进程的定义
2.2. 僵尸进程的特点
2.3. 僵尸进程的产生原因
2.4. 僵尸进程的影响
2.5. 检测方法
2.5. 解决办法
三、孤儿进程(Orphan Process)
3.1. 定义
3.2. 产生原因
3.3. 特点
3.4. 影响
3.5. 处理方式
3.6. 实际应用场景
四、常见问题
4.1. 守护进程的常见问题
4.2. 僵尸进程的常见问题
4.3. 孤儿进程的常见问题
五、参考资料
在嵌入式Linux应用开发中,特殊进程主要包括守护进程、僵尸进程和孤儿进程。
一、守护进程(Daemon Process)
1.1. 概念
守护进程(Daemon Process)是一种在后台持续运行的进程,通常在系统启动时自动启动,直到系统关闭才结束。它不与任何控制终端关联,独立于用户登录和注销操作,主要用于执行一些需要长期运行且不受用户交互影响的系统任务。如日志记录、定时任务等。
1.2. 特点
- 后台运行:守护进程在后台默默工作,不会占用终端,用户可以在终端上进行其他操作,不会受到守护进程的干扰。
- 生命周期长:守护进程通常在系统启动时就开始运行,直到系统关闭才会结束,为系统提供持续的服务。
- 独立于控制终端:守护进程不与任何控制终端相关联,意味着即使控制终端关闭,守护进程也不会受到影响,继续正常运行。
- 权限管理严格:守护进程通常需要特定的权限来执行系统级任务,因此在创建和运行过程中需要进行严格的权限管理。
1.3. 守护进程的命名
守护进程的名称通常以“d”结尾,例如sshd、xinetd、crond等。这种命名约定有助于区分守护进程和普通进程。
1.4. 创建守护进程的步骤
-
创建子进程,父进程退出:通过fork()函数创建子进程,然后父进程使用exit()函数退出。这样,子进程将变成一个孤儿进程,被init进程(PID为1的进程)收养。这一步实现了子进程与父进程的脱离,使得子进程可以在后台运行。
-
在子进程中创建新的会话:使用setsid()函数创建一个新的会话,并设置进程的会话ID。这一步使得子进程成为新会话的会话领导者,并摆脱原会话、进程组和控制终端的控制。
-
更改当前工作目录:通常将守护进程的当前工作目录更改为根目录“/”,以避免因文件系统卸载而导致的问题。
-
重设文件权限掩码:将文件权限掩码设置为0,以确保守护进程具有最大的文件操作权限。
-
关闭所有打开的文件描述符:关闭从父进程继承的所有打开文件,以避免资源泄漏和文件系统无法卸载的问题。通常将标准输入、标准输出和标准错误重定向到/dev/null,使得守护进程的输出无处显示,也无处从交互式用户那里接收输入。
1.5. 守护进程的实例
以下是一个简单的守护进程创建实例:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>int main() {pid_t pid;int i;// 第一步:创建子进程,父进程退出pid = fork();if (pid < 0) {perror("fork");exit(1);} else if (pid > 0) {exit(0); // 父进程退出}// 第二步:在子进程中创建新的会话if (setsid() < 0) {perror("setsid");exit(1);}// 第三步:更改当前工作目录if (chdir("/") < 0) {perror("chdir");exit(1);}// 第四步:重设文件权限掩码umask(0);// 第五步:关闭所有打开的文件描述符for (i = 0; i < sysconf(_SC_OPEN_MAX); i++) {close(i);}// 重定向标准输入、标准输出和标准错误到/dev/nullopen("/dev/null", O_RDWR);dup(0);dup(0);// 守护进程的主体工作while (1) {sleep(10); // 模拟守护进程的工作,每隔10秒执行一次任务// 在这里添加守护进程需要执行的任务代码printf("守护进程运行中...\n"); // 注意:这里的输出实际上会被重定向到/dev/null,因此不会在终端上显示}exit(0);
}
printf("守护进程运行中...\n");语句实际上并不会在终端上显示输出,因为守护进程的标准输出已经被重定向到/dev/null。在实际应用中,守护进程通常会执行一些后台任务,如监听网络请求、处理系统日志等。
1.6. 守护进程的管理
在Linux系统中,可以使用ps、top等命令来查看正在运行的守护进程。如果需要终止某个守护进程,可以使用kill命令向该进程发送SIGKILL或SIGTERM信号。此外,还可以使用nohup命令或&符号将命令放入后台运行,并使其具有一定的守护进程特性(尽管这并不是真正的守护进程)。
1.7. 影响与处理
守护进程可以提高系统的稳定性和可靠性,确保一些重要的服务始终处于运行状态。在开发守护进程时,需要注意资源管理和错误处理,避免守护进程出现异常导致系统不稳定。
二、僵尸进程(Zombie Process)
2.1. 僵尸进程的定义
在Linux系统中,僵尸进程是一种特殊的进程状态。当一个子进程已经完成执行(即已经终止),但其父进程尚未通过wait()或waitpid()系统调用来回收其资源和状态信息时,这个子进程就处于僵尸状态,被称为僵尸进程。
2.2. 僵尸进程的特点
-
进程状态:僵尸进程已经终止,不再执行任何任务,且所有资源(如CPU、内存等)都已释放。然而,它的进程描述符(PCB)仍然保留在系统中。
-
占用系统资源:尽管僵尸进程本身不占用CPU和内存等资源,但它仍然占用进程表中的一个条目,以及保留一定的信息(如进程号PID、退出状态等)。这些信息直到父进程调用wait()或waitpid()时才被释放。
-
无法被直接杀死:僵尸进程已经处于死亡状态,因此无法通过常规的信号(如SIGKILL)将其杀死。只能通过杀死其父进程或等待其父进程主动回收来间接清理僵尸进程。
2.3. 僵尸进程的产生原因
僵尸进程的产生通常是因为父进程没有正确地回收子进程的资源。当子进程退出后,它会发送一个SIGCHLD信号给父进程,通知父进程它已经结束。如果父进程没有处理这个信号或者没有调用wait()系列函数来清理子进程的状态,子进程就会变成僵尸进程。
以下是一个简单的示例代码,演示了僵尸进程的产生:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main() {pid_t pid = fork();if (pid < 0) {perror("fork");return 1;} else if (pid == 0) {// 子进程printf("Child process (PID: %d) is exiting.\n", getpid());exit(0);} else {// 父进程printf("Parent process (PID: %d) is running.\n", getpid());// 父进程不调用 wait() 或 waitpid()sleep(30); printf("Parent process is exiting.\n");}return 0;
}
子进程先退出,但父进程在一段时间内没有调用 wait() 或 waitpid() 来回收子进程的资源,子进程就会变成僵尸进程。
2.4. 僵尸进程的影响
- 系统资源消耗:虽然僵尸进程本身不占用大量资源,但大量僵尸进程会占用进程表中的条目,可能导致进程表耗尽,从而无法创建新的进程。
- 系统性能问题:在资源有限的情况下,僵尸进程可能影响系统的管理和资源分配,进而导致系统性能下降。
2.5. 检测方法
可以使用以下命令来检测系统中的僵尸进程:
ps命令:使用ps -ef或ps aux命令可以查看系统中所有进程的信息。僵尸进程在输出中会显示为<defunct>状态。例如:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1234 0.0 0.0 0 0 ? Z 10:00 0:00 [defunct]
其中,STAT 列显示为 Z 表示该进程是僵尸进程。
top命令:运行top命令后,按下Shift + Z组合键,可以突出显示僵尸进程。僵尸进程会以特殊的颜色显示,方便用户识别。
2.5. 解决办法
为了避免僵尸进程的产生,父进程应该在子进程结束后及时回收其资源。可以采用以下几种方法:
①使用 wait() 函数:wait() 函数会使父进程阻塞,直到有一个子进程结束。父进程调用 wait() 后,会获取子进程的退出状态,并释放子进程的相关资源。示例代码如下:
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>int main() {pid_t pid = fork();if (pid < 0) {perror("fork");return 1;} else if (pid == 0) {// 子进程printf("Child process (PID: %d) is exiting.\n", getpid());exit(0);} else {// 父进程int status;pid_t wpid = wait(&status);if (wpid > 0) {printf("Parent process reaped child process (PID: %d).\n", wpid);}}return 0;
}
②使用 waitpid() 函数:waitpid() 函数比 wait() 函数更加灵活,它可以指定要等待的子进程的 PID,也可以设置非阻塞模式。示例代码如下:
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>int main() {pid_t pid = fork();if (pid < 0) {perror("fork");return 1;} else if (pid == 0) {// 子进程printf("Child process (PID: %d) is exiting.\n", getpid());exit(0);} else {// 父进程int status;pid_t wpid;do {wpid = waitpid(pid, &status, WNOHANG);if (wpid == 0) {// 子进程还未结束,父进程可以继续执行其他任务sleep(1);}} while (wpid == 0);if (wpid > 0) {printf("Parent process reaped child process (PID: %d).\n", wpid);}}return 0;
}
③信号处理:父进程可以通过捕获 SIGCHLD 信号,并在信号处理函数中调用 wait() 或 waitpid() 来回收子进程的资源。示例代码如下:
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>void sigchld_handler(int signum) {int status;pid_t pid;while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {printf("Reaped child process (PID: %d).\n", pid);}
}int main() {// 注册 SIGCHLD 信号处理函数signal(SIGCHLD, sigchld_handler);pid_t pid = fork();if (pid < 0) {perror("fork");return 1;} else if (pid == 0) {// 子进程printf("Child process (PID: %d) is exiting.\n", getpid());exit(0);} else {// 父进程while (1) {sleep(1);}}return 0;
}
三、孤儿进程(Orphan Process)
3.1. 定义
在 Linux 系统里,当一个子进程的父进程提前退出时,这个子进程就会变成孤儿进程。由于父进程已经不存在,孤儿进程会被 init 进程(进程 ID 为 1)收养,成为 init 进程的子进程。
3.2. 产生原因
孤儿进程通常是由于父进程在创建子进程后,未等待子进程结束就提前退出而产生的。这种情况可能出现在多种场景中,例如:
- 父进程完成了自身的任务后正常退出,而子进程仍在执行某些耗时的操作。
- 父进程因发生异常或错误而意外终止,导致子进程失去了父进程的管理。
以下是一个简单的 代码示例,用于演示孤儿进程的产生:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main() {pid_t pid = fork();if (pid < 0) {perror("fork");return 1;} else if (pid == 0) {// 子进程printf("Child process (PID: %d) is running, parent PID: %d\n", getpid(), getppid());sleep(10); // 子进程休眠 10 秒printf("Child process (PID: %d) is still running, new parent PID: %d\n", getpid(), getppid());} else {// 父进程printf("Parent process (PID: %d) is exiting.\n", getpid());exit(0);}return 0;
}
父进程先退出,子进程在一段时间后才会继续执行后续代码。在父进程退出后,子进程的父进程 ID 会变为 1,即被 init 进程收养。
3.3. 特点
- 被
init进程收养:孤儿进程会自动被init进程接管,init进程会成为其新的父进程。init进程会周期性地调用wait()系统调用来回收孤儿进程的资源,确保不会产生僵尸进程。 - 继续执行:孤儿进程并不会因为父进程的退出而终止,它会继续执行自己的任务,直到完成或被其他因素终止。
- 与控制终端失去关联:如果父进程与控制终端有关联,当父进程退出后,孤儿进程会与该控制终端失去关联,成为一个后台进程。
3.4. 影响
- 正常情况下无危害:在大多数情况下,孤儿进程本身不会对系统造成危害。由于
init进程会负责回收孤儿进程的资源,所以不会出现资源泄漏的问题。 - 可能影响系统资源:如果系统中存在大量的孤儿进程,可能会消耗一定的系统资源,如进程表项和内存等。不过,这种情况通常比较少见,因为
init进程会及时回收孤儿进程的资源。
3.5. 处理方式
- 无需特殊处理:一般来说,不需要对孤儿进程进行特殊的处理。
init进程会自动管理和回收孤儿进程的资源,确保系统的正常运行。 - 监控与调试:在开发和调试过程中,可以使用系统工具(如
ps、top等)来监控孤儿进程的状态。例如,使用ps -ef命令可以查看系统中所有进程的信息,通过观察进程的父进程 ID 是否为 1 来判断是否为孤儿进程。
3.6. 实际应用场景
- 守护进程的创建:在创建守护进程时,通常会先创建一个子进程,然后让父进程退出,使子进程成为孤儿进程。接着,子进程再进行一系列操作(如创建新会话、更改工作目录等),最终成为一个守护进程,在后台持续运行。
- 并行任务处理:父进程可以创建多个子进程来并行处理任务,当父进程完成自己的任务后退出,子进程可以继续独立地完成剩余的任务,提高系统的处理效率。
孤儿进程是嵌入式 Linux 系统中一种正常的进程状态,了解其产生原因、特点和处理方式,有助于开发者更好地进行进程管理和系统开发。
四、常见问题
4.1. 守护进程的常见问题
问题1:资源泄漏
-
现象:守护进程长时间运行后内存或文件描述符泄漏,导致系统资源耗尽。
-
原因:
-
未正确关闭文件描述符、套接字或动态分配的内存。
-
第三方库未释放资源。
-
-
解决:
-
使用工具(如
valgrind、strace)检测泄漏。 -
确保所有
malloc/open操作都有配对的free/close。 -
通过
ulimit限制资源使用。
-
问题2:日志管理不当
-
现象:日志文件占满存储空间,系统崩溃。
-
原因:未限制日志大小或未使用循环日志。
-
解决:
-
使用
syslog服务(如rsyslog)集中管理日志。 -
限制日志文件大小(如
logrotate工具)。 -
在资源紧张时关闭调试日志。
-
问题3:信号处理缺失
-
现象:守护进程无法响应
SIGTERM或SIGHUP,导致无法优雅退出或重载配置。 -
解决:注册信号处理函数,使用
sigaction替代signal:
void handle_signal(int sig) {if (sig == SIGTERM) exit(EXIT_SUCCESS);
}
struct sigaction sa;
sa.sa_handler = handle_signal;
sigemptyset(&sa.sa_mask);
sigaction(SIGTERM, &sa, NULL);
问题4:依赖终端环境
-
现象:守护进程意外终止或行为异常。
-
原因:未完全脱离终端(如未正确调用
setsid)。 -
解决:
-
严格遵循守护进程创建步骤(两次
fork)。 -
通过
ps -ef检查进程是否属于独立会话(SID与PID不同)。
-
4.2. 僵尸进程的常见问题
问题1:僵尸进程堆积
-
现象:系统
PID耗尽,无法创建新进程。 -
原因:父进程未调用
wait/waitpid回收子进程。
解决:
- 方案1:父进程注册
SIGCHLD信号处理函数:
void sigchld_handler(int sig) {while (waitpid(-1, NULL, WNOHANG) > 0); // 非阻塞回收所有子进程
}
signal(SIGCHLD, sigchld_handler);
- 方案2:显式忽略
SIGCHLD(部分系统支持):
signal(SIGCHLD, SIG_IGN); // 内核自动回收子进程
问题2:信号竞争(Race Condition)
-
现象:僵尸进程未被及时回收。
-
原因:多个子进程同时退出,信号处理函数漏掉部分
SIGCHLD。 -
解决:在信号处理函数中使用
while + WNOHANG循环,确保回收所有终止的子进程。
问题3:调试困难
-
现象:难以定位僵尸进程的父进程。
-
解决:
-
通过
ps aux | grep Z查找僵尸进程及其父进程PPID。 -
终止父进程(
kill -9 PPID)或强制回收僵尸进程。
-
4.3. 孤儿进程的常见问题
问题1:资源未释放
-
现象:孤儿进程占用文件、套接字或共享内存。
-
原因:父进程终止前未清理子进程资源。
-
解决:
-
父进程应在终止前主动终止子进程。
-
子进程自身需通过
atexit或信号处理释放资源。
-
问题2:预期外的行为
-
现象:孤儿进程逻辑依赖父进程状态(如共享内存)。
-
原因:父进程终止后,子进程仍尝试访问无效资源。
-
解决:
-
子进程应检测父进程状态(如通过
getppid()检查是否变为init)。 -
使用进程间通信(IPC)机制(如管道、信号量)同步状态。
-
五、参考资料
- 《Unix 环境高级编程(第 3 版)》(Advanced Programming in the Unix Environment, 3rd Edition)
- 作者:W. Richard Stevens、Stephen A. Rago
- 简介:这本书是 Unix 和类 Unix 系统编程领域的经典之作。
- 《Linux 系统编程》(Linux System Programming)
- 作者:Robert Love
- 简介:专注于 Linux 系统下的编程技术,详细介绍了守护进程、僵尸进程和孤儿进程的底层原理和实现细节。
- 《深入理解计算机系统(第 3 版)》(Computer Systems: A Programmer's Perspective, 3rd Edition)
- 作者:Randal E. Bryant、David R. O'Hallaron
- 简介:从计算机系统的底层原理出发,阐述了进程的概念、生命周期以及各种进程状态的产生原因。
- Linux 手册页(man pages)
- 获取方式:在 Linux 系统终端中,使用
man命令查看相关内容,如man fork、man wait等;也可访问在线版本 man7.org。 - 简介:这是最权威的 Linux 系统调用参考资料。关于守护进程、僵尸进程和孤儿进程相关的系统调用(如
fork()、wait()、setsid()等)的手册页,详细说明了函数的原型、参数、返回值以及使用示例,是学习和使用这些系统调用的重要依据。
- 获取方式:在 Linux 系统终端中,使用
- GNU C Library 文档
- 获取方式:访问 GNU 官方网站。
- 简介:GNU C Library 是 Linux 系统中广泛使用的 C 标准库,其文档对与进程管理相关的库函数进行了详细描述。
- Stack Overflow
- 获取方式:访问 Stack Overflow 官网,搜索相关问题。
- 简介:这是一个知名的技术问答社区,有大量关于守护进程、僵尸进程和孤儿进程的讨论和问答。
相关文章:
【嵌入式Linux应用开发基础】特殊进程
目录 一、守护进程(Daemon Process) 1.1. 概念 1.2. 特点 1.3. 守护进程的命名 1.4. 创建守护进程的步骤 1.5. 守护进程的实例 1.6. 守护进程的管理 1.7. 影响与处理 二、僵尸进程(Zombie Process) 2.1. 僵尸进程的定义…...
深度学习pytorch之19种优化算法(optimizer)解析
提示:有谬误请指正 摘要 本博客详细介绍了多种常见的深度学习优化算法,包括经典的LBFGS 、Rprop 、Adagrad、RMSprop 、Adadelta 、ASGD 、Adamax、Adam、AdamW、NAdam、RAdam以及SparseAdam等,通过对这些算法的公式和参数说明进行详细解析…...
rust笔记5-derive属性2
在 Rust 中,derive 是一种自动为结构体或枚举实现特定 trait 的机制。通过 #[derive(...)] 属性,Rust 编译器可以自动生成一些常见 trait 的实现代码,从而减少手动编写重复代码的工作量。 以下是对 Copy、Clone、Hash 和 Default 这几个常用 trait 的详细介绍和示例: 1. C…...
DeepSeek、微信、硅基流动、纳米搜索、秘塔搜索……十种不同方法实现DeepSeek使用自由
为了让大家实现 DeepSeek 使用自由,今天分享 10 个畅用 DeepSeek 的平台。 一、官方满血版:DeepSeek官网与APP 首推,肯定是 DeepSeek 的官网和 APP,可以使用满血版 R1 和 V3 模型,以及联网功能。 网址: htt…...
介绍cherrypick
git cherry-pick 是 Git 中的一个强大命令,用于将一个或多个提交(commit)从一个分支应用到另一个分支。它允许你选择性地将特定的变更引入到当前分支,而无需合并整个分支。以下是对 git cherry-pick 操作的详细介绍: 1…...
HTTP、HTTPS区别可靠性及POST为什么比GET安全的探讨
一、简述HTTP协议 HTTP底层是TCP实现,TCP是一个可靠的传输层网络协议,但是可靠性不是安全性——可靠但不安全 1、为什么TCP可靠?UDP不可靠? 可靠指的是源和目标可以相互访问以及确保数据的传输顺序,我能通过IP端口访…...
从零到一:Spring Boot 与 RocketMQ 的完美集成指南
1.Rocket的概念与原理 RocketMQ 是一款由阿里巴巴开源的分布式消息中间件,最初用于支持阿里巴巴的海量业务。它基于发布-订阅模型,具备高吞吐、低延迟、高可用和强一致性的特点,适用于消息队列、大规模数据流处理等场景。以下是对 RocketMQ …...
AIGC:开启内容创作新纪元,我们如何看待它的影响与前景?
AIGC的概念 AIGC(Artificial Intelligence Generated Content)的概念主要是指人工智能生成内容。 这是一种新的人工智能技术,它利用人工智能模型,根据给定的主题、关键词、格式、风格等条件,自动生成各种类型的文本、图…...
10分钟上手DeepSeek开发:SpringBoot + Vue2快速构建AI对话系统
作者:后端小肥肠 目录 1. 前言 为什么选择DeepSeek? 本文技术栈 2. 环境准备 2.1. 后端项目初始化 2.2. 前端项目初始化 3. 后端服务开发 3.1. 配置文件 3.2. 核心服务实现 4. 前端服务开发 4.1. 聊天组件ChatWindow.vue开发 5. 效果展示及源…...
mac安装Pyspark并连接Mysql
安装Scala, apache-spark, Hadoop brew install scala brew install apache-spark brew install hadoop pip install pyspark注意不要自己另外安装jdk, 会造成版本对不上报错。因为安装apache-spark的过程中会自动安装openjdk。 配置环境变量 JAVA_HOME/opt/homebrew/Cellar…...
深入理解Python多进程编程 multiprocessing
深入理解Python多进程编程 multiprocessing flyfish Python 的 multiprocessing 模块允许创建多个进程,从而可以利用多核处理器的能力来并行执行任务。这意味着程序的不同部分可以在不同的CPU核心上同时运行,极大地提高了处理效率,特别是在…...
jQuery AJAX 方法详解
jQuery AJAX 方法详解 引言 随着互联网技术的不断发展,前端开发领域的技术也在不断更新迭代。jQuery 作为一种广泛使用的前端JavaScript库,极大地简化了DOM操作和事件处理。在众多jQuery功能中,AJAX(Asynchronous JavaScript and XML)方法尤为突出,它允许我们在不重新加…...
青少年编程都有哪些比赛可以参加
Python小学生可参加的赛事: 电子学会青少年编程考级、中国计算机学会编程能力等级认证、蓝桥杯、 信奥赛CSP-J/S初赛/NOIP(推荐C)、编程设计、信息素养、科技创新赛; 升学助力(科技特长生、大学)、企业、出国留学; python比赛&am…...
sql server 数据库 锁教程及锁操作
SQL Server数据库 锁的教程 SQL Server 的数据库锁是为了保证数据库的并发性和数据一致性而设计的。锁机制能够确保多个事务不会同时修改同一数据,从而避免数据冲突和不一致的发生。理解 SQL Server 的锁机制对于开发高效、并发性强的数据库应用非常重要。 1. 锁的…...
存储结构 分类
存储结构 1,顺序存储结构 用一组地址连续的存储单元依次存储线性表的各个数据元素, 适用于频繁查询时使用。 2,链式存储结构 在计算机中用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的),适用于在较…...
VSCode 中 Git 添加了多个远端,如何设置默认远端
VSCode 中 Git 添加了多个远端,如何设置默认远端 查看分支:设置默认远端手动指定远端 查看分支: * 表示当前默认远端 git branch -vv* master a1b2c3d [origin/main] Fix typo dev d4e5f6g [upstream/dev] Add feature设置默认远端 将本…...
项目中一些不理解的问题
1.Mybatis是干啥的 他是用来帮我们操作数据库的,相当于是我们的一个助手: 我们想要得到数据库中的什么数据,就可以告诉mybatis,他会给我们想要的结果,同时,我们想要对数据库做出什么操作,也可…...
vue3 + thinkphp 接入 七牛云 DeepSeek-R1/V3 流式调用和非流式调用
示例 如何获取七牛云 Token API 密钥 https://eastern-squash-d44.notion.site/Token-API-1932c3f43aee80fa8bfafeb25f1163d8 后端 // 七牛云 DeepSeek API 地址private $deepseekUrl https://api.qnaigc.com/v1/chat/completions;private $deepseekKey 秘钥;// 流式调用pub…...
Linux应用之构建命令行解释器(bash进程)
目录 1.分析 2.打印输入提示符 3.读取并且处理输入字符串 4.创建子进程并切换 5.bash内部指令 6.完整代码 1.分析 当我们登录服务器的时候,命令行解释器就会自动加载出来。接下来我们就。在命令行中输入指令来达到我们想要的目的。 我们在命令行上输入的…...
php 系统命令执行及绕过
文章目录 php的基础概念php的基础语法1. PHP 基本语法结构2. PHP 变量3.输出数据4.数组5.超全局变量6.文件操作 php的命令执行可以执行命令的函数命令执行绕过利用代码中命令(如ls)执行命令替换过滤过滤特定字符串神技:利用base64编码解码的绕…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...
热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁
赛门铁克威胁猎手团队最新报告披露,数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据,严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能,但SEMR…...
