跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C算法

Linux 进程与 fork 系统调用详解

Linux 进程标识符 PID 用于唯一标识进程。通过 ps 命令可查看所有进程,kill 命令可终止进程。fork 系统调用创建子进程,父子进程共享代码段,数据段采用写时拷贝技术保证独立性。调度器决定进程运行顺序,支持并发执行。Bash 执行命令时隐式调用 fork 创建子进程。理解这些机制有助于掌握操作系统多任务管理。

开源信徒发布于 2026/3/16更新于 2026/5/3019 浏览
Linux 进程与 fork 系统调用详解

进程和 fork

1. 进程的标识符 PID

每个进程都有一个唯一的进程标识符(PID),用于在系统中唯一标识该进程。

1.1 查看系统内所有的进程

在 Linux 中,可以通过 ps 命令查看进程的 PID。

命令:ps

选项:ajx 等

ps -ef # 显示所有进程的详细信息
ps aux # 显示所有用户的所有进程,重在用户
# 我们一般上使用 ps ajx 查看系统内所有的进程
ps ajx # 查看系统内所有的进程 ./proc # 以运行 proc 进程为例
ps ajx | head -1 && ps ajx | grep proc
ps ajx | head -1 && ps ajx | grep proc | grep -v grep

隐藏掉 grep 关键字的命令:ps ajx | head -1 && ps ajx | grep proc | grep -v grep

  • && 表示左边的命令执行完,紧接着执行右边的命令。左边的命令执行成功,右边的命令也要执行成功。
  • ps ajx | head -1 && ps ajx | grep proc 该命令得到的结果会同时显示 proc 进程和 grep 进程。
    • 如果我们不想显示 grep 进程,可以使用管道,对上述命令的结果再进行 grep。
    • ps ajx | head -1 && ps ajx | grep proc | grep -v grep
      • -v 选项配合管道,在已有的结果中反向匹配 grep,可以隐藏掉 grep 关键字。
1.2 kill 杀掉进程

命令:kill [选项] PID

常用选项:-9

功能:

  • kill PID 是温柔的杀掉这个进程。
  • kill -9 PID 向指定 PID 的某个进程发送 9 信号,暴力的杀掉这个进程。

演示:

kill -9 760776 # 强制终止 PID 为 760776 的进程

当使用不带 -9 选项的 kill PID 命令时,默认会向目标进程发送 SIGTERM 信号(信号编号为 15)。与 kill -9(发送 SIGKILL 信号)的强制终止不同,SIGTERM 是一种更友好的终止方式。

kill PID(默认发送 SIGTERM)的行为:

  1. 允许进程优雅退出:进程收到 SIGTERM 后,可以执行清理操作(如保存数据、关闭文件、释放资源等),然后自行终止。
  2. 进程可以捕获或忽略 SIGTERM:如果进程代码中注册了信号处理函数(例如通过 signal() 或 sigaction()),它可以自定义对 SIGTERM 的响应(如延迟退出或忽略信号)。
  3. 可能无法立即终止进程:如果进程因代码缺陷、死锁或无限循环无法响应 SIGTERM,它可能不会退出。此时需手动使用 kill -9 强制终止。

kill -9 PID(发送 SIGKILL)的行为:

  1. 强制立即终止进程:SIGKILL 信号无法被进程捕获或忽略,操作系统会直接终止进程,不给进程任何清理的机会。
  2. 可能导致资源泄漏:进程无法执行清理操作,可能导致临时文件残留、内存未释放、文件句柄未关闭等问题。
  3. 适用于无响应的进程:当进程对 SIGTERM 无响应时,SIGKILL 是最后手段。

使用建议:

  1. 优先使用默认的 kill PID(SIGTERM):给进程机会优雅退出,避免数据丢失或资源泄漏。
  2. 仅在必要时使用 kill -9(SIGKILL):例如进程完全卡死、僵尸进程或恶意进程等情况。

扩展知识:

  • 查看所有信号:kill -l
  • 常用信号:
    • SIGHUP (1):挂起(重新加载配置)
    • SIGINT (2):中断(同 Ctrl+C)
    • SIGTERM (15):终止
    • SIGKILL (9):强制终止

通过合理选择信号,可以更安全地管理系统进程。

1.3 获取进程的 PID

Linux 操作系统中,描述系统进程的 task_struct 是用双向链表组织的。

  • 进程的 PID 也是进程的属性,因此 PID 属性存在于进程的 task_struct 中。
  • ps ajx 的本质作用,相当于遍历 task_struct 的链表,拿到所有进程的相关属性,打印出来,供我们查看 PID。
  • 既然可以拿到所有进程的相关属性,那么对于一个特定进程的 PID,应当也是可以获取到的。

操作系统不相信任何用户,不能让用户通过 task_struct.pid 的方式通过结构体直接访问 PID。因此操作系统一定对外提供了系统调用接口,供用户访问 task_struct 内描述进程的相关属性。

在 Linux 中,可通过系统 getpid() 或 getppid() 调用获取进程的 PID:

  • pid_t getpid():获取当前进程的 PID。
  • 进程都是被创建出来的,一个进程除了有自己的 PID,也有自己的父进程,父进程的 PID 也可以被获取到。
  • pid_t getppid():获取父进程的 PID。
  • 返回值类型均为 pid_t,本质是 int 的类型别名。typedef int pid_t

getpid 代码演示

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main() {
    pid_t pid = getpid();
    pid_t ppid = getppid();
    // pid_t 本质是有符号整数
    while(1) {
        printf("I am a process, my ID is %d, my parent ID is %d\n", pid, ppid);
        sleep(1);
    }
}

我们可以手动将 ps ajx 配合 grep 命令,制作一个系统内进程监控脚本,监控系统内进程的信息。

while :; do
    ps axj | head -1 ;
    ps ajx | grep proc | grep -v grep | grep -v .vscode;
    sleep 1;
done
  • sleep 1:每秒执行一次。
  • ps axj | head -1 ; ps ajx | grep proc | grep -v grep | grep -v .vscode:过滤我们的 proc 进程,不显示 grep 命令本身的进程和 .vscode 远程连接的进程。
  • 我们可以手动在终端中执行以上命令。也可以将以上内容保存在一个后缀为.sh 的文件中,这里我选择保存为一个 sh 文件,并命名为 monitor.sh。

保存后,为当前文件增加执行权限后并执行:

chmod u+x monitor.sh # 增加执行权限
bash monitor.sh # 执行脚本

可以看到:

  • 进程启动前,检测脚本未检测到任何内容。
  • 进程启动后,检测脚本就检测到了我们启动的 proc 进程。
  • 且 ps ajx 查看到的 PID 及 PPID 和 getpid() 和 getppid() 获取到的内容完全一致!!!
  • 这样我们就可以通过 PID 来对进程进行管理了。
1.4 bash 与父子进程

观察以下现象,注意 proc 进程的 PID。

  • 一个程序,多次启动时 PID 在变。
    • 这是因为:PID 只保证在每次运行期间有效,下次启动,操作系统为该进程分配的 PID 可能会变化,这是正常的。
  • 一个程序,多次启动时的 PID 在变,其父进程的 PID 一直不变。这是为什么?父进程的 PID 一直是 761739,这里的父进程是什么进程?
  • 这里可以清楚的看到,761739 在这里就是我们的命令行解释器 bash!

我们来查看 PID 为 761739 的进程:

ps ajx | head -1 && ps ajx | grep 761739

Bash(命令行解释器)本身是一个进程,用户执行的命令(如 ls、./a.out 等)均为 Bash 的子进程。Bash 的 PID 在单次登录会话中固定,但重新登录后会变化。

我们在命令行解释器 bash 中,执行的所有指令(包括命令和./执行的程序)的父进程,就是 bash 本身。

  1. 每次重新登陆 xshell 时,Linux 系统会单独为我们创建一个 bash 进程,即为我们创建一个命令行解释器进程,帮我们在显示器中打印出命令行终端。
  2. 我们在命令行解释器中,执行或输入的所有指令和程序,bash 都会为我们创建进程,这些程序都是 bash 的子进程。 bash 只负责命令行解释,具体执行出问题时,只会影响对应的子进程。因此在同一登陆状态下,指令和程序的父进程 PID 不变,也就是 bash 的 PID 不变。
  3. 一个 bash 有一个 PID,多开多个 bash,会有多个 bash PID。
  4. 进程主要维护父子关系。只有父子进程,没有母子进程或爷爷进程。

./操作执行程序或者命令时,就是操作系统为我们创建了一个进程,在操作系统上运行。

父子进程关系特点:

  1. 父进程负责管理子进程。
  2. 子进程退出后,父进程需要通过 wait 系统调用回收资源。
  3. 若父进程先退出,子进程会成为孤儿进程,由 init 进程(PID=1)接管。

2. 创建进程与 fork

2.1 fork 创建子进程

以上我们介绍了获取父子进程 PID 相关的知识,那么我们用户可否创建一个进程呢?

我们目前已知的创建进程的方式:

  • ./exe 操作,执行程序或者执行命令时,就是操作系统为我们创建了一个进程,在操作系统上运行。这是指令级别创建进程。

这种方式是我们手动创建进程,那么可否在程序运行时创建进程呢?

Linux 内核为我们提供了系统调用 fork(),用于为当前进程创建一个子进程。这是代码级别创建进程。

fork 是 Linux 中创建子进程的核心系统调用,可以在程序运行时创建进程,其独特的行为常引发初学者的困惑。

使用 man 手册查看 fork 函数的用法

man 2 fork
  • 函数名和功能:fork

    • 为当前调用 fork 的进程创建一个子进程。
    • 新进程为子进程 (child process),当前调用进程为父进程 (parent process)。
    • 子进程复制父进程的代码、数据、堆栈和打开的文件描述符。
  • 头文件:<sys/types.h> 和 <unistd.h>

  • 参数类型:void 无需传参

  • 返回值:类型为 pid_t,这里 pid_t 是 int 的类型别名。typedef int pid_t

  • 根据文档介绍,

    • 创建子进程失败时,在父进程(原进程)中返回 -1,并设置 errno。
    • 成功时:
      • 在父进程中返回子进程的 PID。
      • 在子进程中返回 0。

fork 的简单使用:

int main() {
    printf("before: only one line\n");
    fork();
    printf("after: only one line\n");
    sleep(1);
}

这里我们不免会有疑惑???

==fork 之后的代码,执行了两次!!!==这是为什么?

先给出结论:fork 之后的代码,父子进程是共享的,既然父子进程各有一份代码 (共享),那 fork 之后的代码执行了两次就可以说得通了。

再看如下代码和现象:

  • 这里 ./proc 是当前进程,fork 之后,现象是:代码被一分为二了,两个循环各自在执行,父子进程各执行一个循环。这说明,id == 0 和 id > 0 同时成立了,且根据进程的 PID,我们可以得出:
    • 执行 fork 之后当前进程是父进程。
    • 其子进程是由 fork 创建的。
    • 当前进程(调用 fork 的进程)的父进程是 bash 进程。
  • fork 之后一定存在两个进程,存在两个执行流。

以上种种现象,我们不免产生很多疑问???

  1. 为什么 fork 要给子进程返回 0,给父进程返回子进程的 pid 呢?为什么父子进程的返回值不同呢?
  2. 一个函数,怎么会有两个返回值,如何做到返回两次呢?
  3. 变量 id 接收 fork 的返回值,为什么一个变量可以有两个不同的值?
  4. fork 函数内究竟做了什么?

这些问题我们后文会一一解答。

2.2 fork 困惑的解释

结合 fork 的翻译,分支,分叉,表示我们的代码在 fork 这里要进行分叉。

0. fork 的工作原理
  1. 创建子进程的 PCB:内核为子进程分配新的 task_struct。
  2. 复制父进程上下文:子进程继承父进程的代码段、数据段、堆栈和文件描述符表。
  3. 分流执行:fork 返回后,父子进程从同一位置继续执行,但通过返回值区分逻辑分支。
1. 为什么给子进程返回 0,给父进程返回子进程 PID

**结论:**一般而言,fork 之后的代码,父子共享。

解答这个问题,先思考我们为什么要创建子进程?

  • 是为了让父子进程协作,执行不同的事情,因此需要想办法让父子进程执行不同的代码块。为了让父子进程协同,执行不同的执行流,就设计了 fork 返回值要不同。

为什么要父子进程要分别返回不同的值?

  • 是为了在 fork 之后,可以根据不同的返回值区分父子进程,来让父子进程执行不同的代码片段。
  • 返回不同的返回值,是为了区分。让不同的进程执行流,执行不同的代码块。

为什么给子进程返回 0,给父进程返回子进程的 PID?

因为:

  • 一个子进程只会有一个父进程,一个父进程可能会有多个子进程。
  • 父进程需要管理多个子进程,通过子进程的 PID 来区分不同的子进程。
    • 父进程需要区分不同的子进程:给父进程返回子进程的 PID,用 PID 来标识子进程的唯一性,方便直接通过不同的 PID,对不同的子进程直接做控制。
  • 子进程只需确认自身身份,返回 0 简化逻辑判断。
    • 一个子进程只有一个父进程。标识子进程,只需要在父进程内判断 fork 的返回值是否 PID == 0 即可标识子进程。子进程得到父进程的 PID,只需要调用 getppid() 函数即可。
2. 一个函数如何做到返回两次?如何理解?
2.1 为什么父子进程共享 fork 之后的代码

原因如下:

  • 进程 = 内核数据结构 + 代码和数据。
  • fork 创建子进程,也就是内存中多了一个进程,Linux 操作系统会为该子进程创建一个 task_struct。
  • 创建子进程前,该进程(父进程)有自己的 task_struct 和代码和数据。创建子进程,操作系统层面只创建了子进程的 task_struct,子进程没有自己的代码和数据,只能和父进程共享同一份代码。因此 fork 之后,父子进程代码共享。
    • 代码加载到内存后,代码是不可修改的。能改的只有代码中的数据。
  • 因此 fork 之后,父子进程共享后续的代码。
  • 数据呢?(下文解释)

fork 之后,父子进程共享后续的代码。fork 之后父子进程执行的代码一样,那我们为什么要创建子进程呢?我们的目的就是为了让父子进程协同起来分别做不同的事情。因此需要想办法让父子进程执行不同的代码块。fork 函数具有不同的返回值,就是为了让父子进程执行不同的代码块而设计的。

那么 fork 如何设计实现了以上功能?

2.2 理解一个函数做到返回两次

代码示例:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main() {
    printf("begin:我是一个进程,pid: %d, ppid: %d\n", getpid(), getppid());
    pid_t id = fork();
    if(id == 0) {
        // 子进程分支
        while(1) {
            printf("我是子进程,pid: %d, ppid: %d\n", getpid(), getppid());
            sleep(1);
        }
    } else if(id > 0) {
        // 父进程分支 成功时,子进程的 PID > 0 返回到父进程
        while(1) {
            printf("我是父进程,pid: %d, ppid: %d\n", getpid(), getppid());
            sleep(1);
        }
    } else {
        // error
    }
    return 0;
}
  • fork 有不同的返回值?一个函数如何做到返回两次?

解释如下:

  • 任何一个函数在即将 return 时,这个函数的核心功能就已经完成了。
  • fork 是一个函数,内部的实现是要创建子进程。fork 函数做的关键步骤:
    • 为子进程创建 task_struct(PCB)。
    • 用父进程的字段初始化子进程。
    • 使父子进程的 task_struct(PCB) 指向同一块代码和数据,父子进程仅实现代码共享。
      • 子进程对父进程中的数据,实行的是,读时共享,写时拷贝。
    • 完成所有工作后 return。
  • return 之前,父子进程都已存在,各自有独立的 task_struct,且可以被 CPU 调度。此时在临界执行 return 之前,父子进程的 task_struct(PCB) 都已存在了,父子进程也都已存在。

return 执行之前父子进程均已创建完成,且可以被 CPU 调度。创建子进程后,父子进程代码共享,return 语句也属于代码,因此父子进程共享 return 语句。CPU 分别调度父子进程,父进程和子进程分别执行了 return,就实现了一个函数返回两次。

fork 在即将执行 return 之前,创建子进程的工作已经完成了,子进程也允许被 CPU 调度了,之后的 return 代码父子进程共享,父和子进程分别执行 return,因此 fork 函数就实现了返回两次。

2.3 fork 函数内做了什么?

综上我们可以总结出 fork 内部究竟做了什么:

  • 创建子进程。
  • 为子进程创建 PCB。
  • 用父进程的字段初始化子进程。
  • 让父子进程实现代码共享。
  • …其他工作。
3. 一个 id 变量里面怎么会有两个值

任何平台下,进程在运行时具有独立性!进程的运行互不干扰。

  • 数据有可能会被修改,代码是相同的且不可被修改。一个进程修改了数据,由于代码是相同的,可能会影响到另一个进程的运行。因此父子进程不能共享同一份数据。

    • 代码不可被修改,因此共享代码不会影响父子进程的独立性。
  • 一个 id 变量里面有两个值的现象,实际是通过写时拷贝实现的。

  • 子进程刚被创建时,代码和数据都是父子进程共享的。 代码加载到内存中后,是不可修改的,因此代码直接父子共享。

  • 子进程在读取父进程的数据时,数据也是共享的。当子进程尝试修改父进程的数据时,操作系统为子进程新分配一块内存空间,让子进程对待修改数据的拷贝进行修改,要修改多少内容,就申请多少空间,从而不会影响到父进程的数据,该过程称为写时拷贝。

  • 以后子进程只要修改父进程的数据,操作系统都会给子进程在内存中新拷贝一份,供子进程修改。

以上称为父子进程之间,数据层面的写时拷贝,写时拷贝保证了父子进程间数据的独立性,避免了父或子进程修改数据后对子或父进程的数据产生影响。

3.1 写时拷贝

fork 之后父子进程共享代码段,但数据段通过写时拷贝(COW——Copy-On-Write)技术实现高效复制。

原理:

  • 子进程创建时,与父进程共享物理内存。
  • 当子进程尝试修改内存时,内核会为该内存页创建副本,确保修改的独立性。

优点:

  • 减少内存全量复制开销。
  • 提高 fork 的执行效率。
3.2 fork 中的写时拷贝
  • return 时,return 是对 id 做写入。
  • return 语句父子进程共享,父子进程分别 return。
  • 父进程 return 时,直接对 id 做写入;子进程 return 时,对 id 做写时拷贝。

3. 进程与调度器

问题:fork() 后父子进程谁先运行?

当调用 fork() 创建子进程后,父子进程会被同时放入操作系统的就绪队列中等待执行。它们的运行顺序由操作系统的进程调度器决定,用户无法预测或干预。这是操作系统的核心设计原则之一:调度器尽可能保证公平性,而非确定性。因此 fork() 后父子进程谁先运行,无法确定,取决于调度器。

调度器的工作原理

  1. 进程的组织形式 所有进程的 PCB(进程控制块)以数据结构(如链表、队列、树等)组织在内存中,例如:
    • 就绪队列:等待 CPU 时间的进程。
    • 阻塞队列:等待 I/O 或其他资源的进程。
  2. 调度器的核心任务 调度器从就绪队列中选择一个进程分配 CPU 时间,具体流程如下:
    • 触发时机:时钟中断、进程阻塞、进程退出等。
    • 选择算法:通过调度算法(如时间片轮转、优先级调度)选择下一个进程。
    • 上下文切换:保存当前进程的 CPU 状态(寄存器、程序计数器等),加载目标进程的上下文。

常见的调度算法

算法特点
先来先服务 (FCFS)简单,但可能导致饥饿现象
时间片轮转 (RR)每个进程分配固定时间片,公平性强,适合交互式系统
优先级调度高优先级进程优先执行,需防止低优先级进程饿死
多级反馈队列结合时间片和优先级,动态调整进程优先级,兼顾响应时间和吞吐量

为什么单核 CPU 能同时运行数百个进程?

  1. 并发假象 调度器通过快速切换进程(纳秒级时间片)营造并行假象。例如:
    • 进程 A 运行 5ms → 切换到进程 B 运行 5ms → 切换回进程 A……
    • 人类无法感知微小的时间片切换,因此感觉多个进程在同时运行。
  2. 父子进程的竞争 在 fork() 后,父子进程进入就绪队列,可能发生以下情况:
    • 父进程先获得 CPU 时间(常见,因父进程可能处于活跃状态)。
    • 子进程先获得 CPU 时间(可能因父进程被阻塞或时间片耗尽)。
    • 父子进程交替执行(取决于调度策略和系统负载)。

4. bash 与 fork

bash 也是通过 fork 创建子进程的

Bash 执行命令的流程

当在 Bash 中输入命令(如 ls -l)时,Bash 的底层操作如下:

  1. fork():创建子进程
    • 子进程复制父进程(Bash)的内存、文件描述符、环境变量等。
    • 优化技术:写时复制 (Copy-On-Write),仅在数据被修改时复制内存,减少开销。
  2. exec():加载新程序
    • 子进程调用 exec() 系统调用,用目标程序(如 /bin/ls)替换当前内存空间。
  3. wait():父进程等待
    • Bash(父进程)调用 wait() 阻塞自身,直到子进程结束并回收资源。
    • 若未调用 wait(),子进程退出后会成为僵尸进程(Zombie),占用系统资源。

5. 结语

进程是操作系统资源分配的基本单位,而 fork 作为创建子进程的核心机制,通过代码共享、写时拷贝和调度器的协同工作,实现了高效的多任务管理。理解父子进程的关系、fork 的分流特性以及调度器的随机性,是掌握进程管理的关键。无论是 bash 执行命令时的隐式 fork,还是程序内显式创建子进程,本质都在通过进程的独立性完成并发任务。写时拷贝技术平衡了性能与资源隔离,而调度器的公平策略让单核 CPU 也能营造并行假象。希望本文为你揭开了进程与 fork 的神秘面纱。

目录

  1. 进程和 fork
  2. 1. 进程的标识符 PID
  3. 1.1 查看系统内所有的进程
  4. 我们一般上使用 ps ajx 查看系统内所有的进程
  5. 1.2 kill 杀掉进程
  6. 1.3 获取进程的 PID
  7. 1.4 bash 与父子进程
  8. 2. 创建进程与 fork
  9. 2.1 fork 创建子进程
  10. 2.2 fork 困惑的解释
  11. 0. fork 的工作原理
  12. 1. 为什么给子进程返回 0,给父进程返回子进程 PID
  13. 2. 一个函数如何做到返回两次?如何理解?
  14. 2.1 为什么父子进程共享 fork 之后的代码
  15. 2.2 理解一个函数做到返回两次
  16. 2.3 fork 函数内做了什么?
  17. 3. 一个 id 变量里面怎么会有两个值
  18. 3.1 写时拷贝
  19. 3.2 fork 中的写时拷贝
  20. 3. 进程与调度器
  21. 4. bash 与 fork
  22. 5. 结语
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • (第二篇)Spring AI 实战进阶:从 0 搭建 SaaS 模式多租户 AI 客服平台(核心难点 + 性能优化全解析)
  • Java Web 开发环境搭建:IDEA 与 Tomcat 安装部署指南
  • AIGC 时代下前端开发范式迁移与工程师成长路径
  • 利用闲置安卓手机与天马G打造复古掌机
  • 皮带输送机 7×24h 全域智能巡检机器人方案
  • AI 自动生成 SQL 查询语句的性能优势与 DBA 视角深度对比
  • 基于 Web 的足球青训俱乐部管理系统设计与实现
  • IntelliJ IDEA 运行时报错 ExceptionInInitializerError 解决方案
  • C++ 类的 6 个默认成员函数与运算符重载详解
  • ToDesk ToClaw 评测:基于 OpenClaw 的零门槛 AI 桌面自动化
  • OIS 防抖结构、闭环控制与 ISP 融合调优
  • 2026 年 3 月 26 日全球 AI 前沿动态:模型、智能体与硬件突破
  • Python 人工智能入门指南
  • 前端可访问性开发指南
  • Python 中 del 语句与垃圾回收机制深度解析
  • Java 程序员面试核心考点与准备指南
  • 小米智能家居 Miloco 分离式部署指南
  • 使用 DeepFace 和 OpenCV 实现情绪分析器
  • 工业级大模型落地挑战及难点解析
  • 递归算法找出所有子集的异或总和再求和

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online