最新资讯

  • 【Linux】进程间通信:详解 VSCode使用 | 匿名管道

【Linux】进程间通信:详解 VSCode使用 | 匿名管道

2025-04-30 13:00:49 1 阅读

目录

0. 引入:vscode 的使用

下载

推荐插件

连接云服务器

1. 进程间通信

1.1 是什么

1.2 为什么

1.3 怎么办

介绍 :

2. 匿名管道

2.1 引入

2.2 原理

3. 建立管道的系统调用pipe

3.1 介绍

形参

返回值

3.2 代码

3.3 站在内核的角度

编码实现


0. 引入:vscode 的使用

下载

官⽹下载地址:https://code.visualstudio.com/Download

下载太慢,推荐下载链接:

https://vscode.cdn.azure.cn/stable/30d9c6cd9483b2cc586687151bcbcd635f373630/VSCodeUser

然后一直 next 安装即可

推荐插件

安装完成后在如下地方,继续安装插件即可

  1. Remote - SSH - 远程登录Linux
  2. C/C++ - 必装
  3. C/C++ Extension Pack - C/C++扩展包,下载直接安装,它包含了 vscode 编写 C/C++ ⼯程需要的插件(C/C++、C/C++ Themes、CMake、CMake Tools和Better C++ Syntax等),和以前⽐不需要⼀个个找了。
  4. C/C++ Themes - 主题设置,插件⾥⾯可以点击设置
  5. Chinese (Simplified) (简体中⽂)
  6. vscode-icons - 改变编辑器⾥⾯的⽂件图标
  7. filesize - 左下⻆显⽰源⽂件⼤⼩的插件
  8. Include AutoComplete - ⾃动头⽂件包含
  9. GBKtoUTF8 - ⾃动将 GBK 转换为 UTF8

连接云服务器

安装如下软件后,对照 README 操作,输入主机号即可

可以在我的电脑的如下路径下查看 config ,检查连接

记事本查看

连接完成后,打开需要的文件夹即可

使用小tips:

  • ctrl ~ :打开终端
  • ctrl s : 保存文件
  • ctrl/ :可以实现注释

1. 进程间通信

1.1 是什么

  • 数据传输:一个进程需要将它的数据发送给另一个进程。
  • 资源共享:多个进程之间共享同样的资源。
  • 通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。
  • 进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。

1.2 为什么

为了实现两个或者多个进程实现数据层面的交互,因为进程独立性的存在,导致进程通信的成本比较

通信可以用于:1. 基本数据 2. 发送命令 3. 某种协调 4. 通知 ...很多场景下需要多个进程协同工作来完成要求。例如

两个进程cat和grep协同工作,将log.txt文件中带有hello的文字显示出来。

1.3 怎么办

当前主要是通过三种策略来实现进程间通信的:

管道:通过文件系统通信

  • 匿名管道
  • 命名管道

System Ⅴ:聚焦在本地通信

  • 共享内存
  • 消息队列
  • 信号量

POSIX:让通信可以跨主机

  • 共享内存
  • 消息队列
  • 信号量
  • 互斥量
  • 条件变量
  • 读写锁

每一种策略下都有很多种通信方式,在这篇文章中将详细讲解管道策略的通信方式。

介绍 :

a. 进程间通信的本质:必须让不同的进程看到同一份“资源

b. 资源?特定形式的内存空间

c. 这个资源谁提供?一般是操作系统

为什么不是我们两个进程中的一个呢?假设一个进程提供,这个资源属于谁?

这个进程独有,破坏进程独立性,所以要借用第三方空间

d. 我们进程访问这个空间,进行通信,本质就是访问操作系统!

进程代表的就是用户,资源从创建,使用(一般),释放--系统调用接口

从底层设计,从接口设计,都要由操作系统独立设计,一般操作系统,会有一个独立的通信模块--隶属于文件系统--IPC 通信模块

定制标准 -- 进程间通信是有标准的 -- system V && posix

e. 基于文件级别的通信方式 --管道

2. 匿名管道

2.1 引入

父子间通信仍然正常进行,并且效率还非常的高,而且还没有影响进程的独立性。而这种不进行IO(不刷到磁盘),就是内存级文件

这种由文件系统提供公共资源的进程间通信,就叫做管道

2.2 原理

匿名管道:没有名字的文件(struct file)。

匿名管道用于父子间通信,或者由一个父创建的兄弟进程(必须有“血缘“)之间进行通信

现在我们知道了匿名管道就是没有名字的文件,通过管道进行通信时,只需要通信双方打开同一个文件就可以。

我们通过系统调用open打开文件的时候,会指定打开方式,是读还是写。

  • 当父进程以写方式打开一个文件的时候,创建的子进程会继承父进程的一切
  • 此时子进程以写的方式打开的这个文件。

既然是通信,势必有一方在写,一方在读,而现在父子双方都是以写的方式打开,它们怎么进行通信呢?

父进程以读和写的方式打开同一份文件两次。可以理解为管道就是文件,有缓冲区,由父子进程引入管道文件

父进程拷贝创建出子进程,PCB 是肯定要的,files_struct 指向同一文件

父子进程公用文件实现了,那么对于读写的控制是怎么实现的呢?

  • 为了防止父进程对管道进行误读,以及子进程对管道进行误写,破坏通信规则。
  • 将父进程的读端关闭,将子进程的写端关闭,使用系统调用close(fd)。

只想让父子进程进行单向通信!所以称为管道通信。把文件这套拿过来,用就是为了简单

我们想让子进程进行写入,父进程进行读取

细节图

如果我要进行双向通信呢?多个管道

如果文件没有任何关系,可以用我们刚刚讲的原理进行通信呢?

不能,必须是父子关系/兄弟关系/爷孙关系...进程之间需要有血缘关系,常用于父子,才能继承一套 file_struct。制作如下动图

sum: 至此,通信了吗??没有。建立通信信道--为什么这么费劲?--因为进程具有独立性,要操作系统忙活才能建立出信道,通信是有成本的!

3. 建立管道的系统调用pipe

3.1 介绍

上面都是理论上的,具体到代码中是如何建立管道的呢?既然是操作系统中的文件系统提供的公共资源,当然是用系统调用来建立管道了。

man 2 pipe

形参
  • int pipefd[2] 是一个输出型参数,表示一个数组,该数组有两个元素,下标分别为0和1。
    • 下标为0的元素表示管道读端的文件描述符 fd。(0像张嘴读书)
    • 下标为1的元素表示管道写端的文件描述符 fd。(1像拿笔写字)

通过系统调用 pipe,可以直接获得这两个文件描述符,并将其添加到父进程的文件描述符表中,无需两次打开内存级别的文件。

返回值
  • 返回值为 int 类型的整数,用来反馈管道创建的情况。
    • 返回0表示管道创建成功。
    • 返回-1表示管道创建失败,并且会将错误码自动写入 errno 中。

那么,父进程创建管道后,得到的两个文件描述符是多少呢?是3和4吗?我们可以通过代码来验证这一点。

输出型参数:文件的描述符数字带出来,让用户使用-->3,4,因为0,1,2分别被stdin,stdout,stderr占用。

3.2 代码

下面代码示例展示了如何通过管道(pipe)在父子进程之间进行通信。为了更好地理解代码,我们将其拆分开来并逐段解释每部分的含义。

#include     // 包含pipe, fork, waitpid, write, read等函数的头文件
#include  // 包含pid_t类型的头文件
#include       // 包含std::string类的头文件
#include     // 包含std::cout, std::endl等输入输出流的头文件
#include      // 包含exit函数和一些其他通用函数的头文件

这些头文件提供了程序中使用的函数和类型的声明。

const int NUM = 100; // 定义缓冲区大小
const int N = 2;     // 定义管道数组的大小

这两行代码定义了一些常量,NUM 是缓冲区的大小,N 是管道数组的大小。

void Writer(int wfd) {
    std::string s = "hello, I am child";
    pid_t self = getpid();
    int number = 0;

    char buffer[NUM]; // 定义一个缓冲区

    while (true) {
        sleep(1);

        // 构建发送字符串
        snprintf(buffer, sizeof(buffer), "%s-%d-%d", s.c_str(), self, number++);
        // 发送/写入给父进程, system call
        write(wfd, buffer, strlen(buffer) + 1); // 注意这里需要加1来包括''

        std::cout << number << std::endl;

        if (number >= 5) break;
    }
}

这个函数Writer用于子进程向父进程写入数据。wfd是写端文件描述符,s是发送的字符串,self是子进程ID,number是一个计数器。每次循环中,构建一个包含字符串、子进程ID和计数器的消息,然后写入管道。每写一次,计数器加一,循环5次后退出。

void Reader(int rfd) {
    char buffer[NUM];

    while (true) {
        buffer[0] = 0;
        ssize_t n = read(rfd, buffer, sizeof(buffer));
        if (n > 0) {
            buffer[n] = 0; // 终止字符串
            std::cout << "father get a message[" << getpid() << "]# " << buffer << std::endl;
        } else if (n == 0) {
            std::cout << "father read file done!" << std::endl;
            break;
        } else {
            std::perror("Error reading from pipe"); // 打印错误信息
            break;
        }
    }
}

这个函数Reader用于父进程从管道读取数据。rfd是读端文件描述符。每次循环中,尝试从管道读取数据,如果成功读取到数据,将其打印出来。如果读取到文件结尾或发生错误,则退出循环。

主函数中:

  1. 创建一个管道,pipefd数组包含两个文件描述符,一个用于读,一个用于写。
  2. 调用fork()创建子进程。
  3. 如果fork()失败,打印错误信息并退出。
  4. 如果是子进程,关闭读端,调用Writer函数写数据,写完后关闭写端并退出。
  5. 如果是父进程,关闭写端,调用Reader函数读数据,等待子进程结束,关闭读端。
  6. 最后,打印程序结束的信息并返回。
int main() {
    int pipefd[N] = {0}; // 管道文件描述符
    int n = pipe(pipefd);
    if (n < 0) {
        std::perror("Error creating pipe");
        return 1;
    }

    pid_t id = fork(); // 创建子进程
    if (id < 0) {
        std::perror("Error forking");
        return 2;
    }
    if (id == 0) { // 子进程
        close(pipefd[0]); // 关闭读端

        Writer(pipefd[1]); // 写入数据

        close(pipefd[1]); // 关闭写端
        exit(0);
    } else { // 父进程
        close(pipefd[1]); // 关闭写端

        Reader(pipefd[0]); // 读取数据

        pid_t rid = waitpid(id, nullptr, 0);//回收子进程
        if (rid < 0) {
            std::perror("Error waiting for child process");
            return 3;
        }

        close(pipefd[0]); // 关闭读端
    }

    std::cout << "Program finished." << std::endl;
    return 0;
}

回忆点:

  1. return 2 的设置 : 如果 fork() 失败,程序将返回 2。这里的数字 2 是一个约定的返回值,用于表示 fork() 调用失败。通常情况下,不同的错误情况会使用不同的返回值来区分。
  2. 子进程关闭管道的写端 (pipefd[1]) 并随后调用 exit(0) 是为了:确保子进程只执行写操作,一旦写操作完成,子进程就退出
  3. pid_t rid = waitpid(id, nullptr, 0) :使用 waitpid 函数来等待子进程的结束,结束后父进程一定要实现资源回收
  • waitpid 是一个系统调用,用于等待指定子进程的终止状态。
  • 参数 id 是子进程的 PID(进程标识符)。
  • 参数 nullptr 表示不关心子进程的状态信息。
  • 参数 0 表示默认的行为,即等待任何子进程的终止。

运行:

批注:

  1. buffer[0] = 0; - 清空字符串,标志数组 buffer 作为字符串使用。
  2. buffer[n] = 0; --终止字符串,进行打印
  3. snprintf(buffer, sizeof(buffer), "%s-%d-%d", s.c_str(), self, number++); - 使用安全的格式化函数,防止缓冲区溢出。

snprintf 参数设计简洁说明:

  • buffer:目标字符数组,用于存储格式化后的字符串。
  • sizeof(buffer):指定缓冲区大小,防止溢出。
  • "%s-%d-%d":定义字符串格式,包含字符串、两个整数和一个分隔符。
  • s.c_str():提供要插入的字符串。
  • self:插入的第一个整数。
  • number++:使用并递增的第二个整数。

完整代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include  // 包含snprintf和perror的头文件

const int NUM = 100; // 缓冲区大小
const int N = 2;     // 管道数组的大小
using namespace std;

void Write(int wfd) {
    string s = "hello, I am child";
    int number = 0;
    char buffer[NUM]; // 定义一个缓冲区
    while (true) {
        sleep(1);
        snprintf(buffer, sizeof(buffer), "%s-%d-%d", s.c_str(), getpid(), number++);
        // 构建字符串
        write(wfd, buffer, sizeof(buffer)); // 实现传参写入
        cout << number << endl; // 打印计数
        if (number >= 5) break;
    }
}

void Reader(int rfd) {
    char buffer[NUM];
    while (true) {
        buffer[0] = 0;
        ssize_t n = read(rfd, buffer, sizeof(buffer)); // 读取缓冲区
        if (n > 0) {
            buffer[n] = 0; // 终止字符串,打印
            cout << "father get a message[" << getpid() << "]# " << buffer << endl;
        } else if (n == 0) {
            cout << "father read file done!" << endl;
            break;
        } else {
            perror("Error reading from pipe"); // 打印错误信息
            break;
        }
    }
}

int main() {
    int pipefd[N] = {0}; // 管道数组描述符
    int n = pipe(pipefd);
    if (n < 0) {
        perror("Error pipe");
        return 1;
    }

    pid_t id = fork(); // 创建子进程
    if (id < 0) {
        perror("Error forking");
        return 2; // 回忆点1
    }
    if (id == 0) {
        // 子进程
        close(pipefd[0]);
        Write(pipefd[1]); // 传入写端
        close(pipefd[1]);
        exit(0); // 回忆点2
    } else {
        // 父进程
        close(pipefd[1]);
        Reader(pipefd[0]);

        // 回忆点3
        // 等待回收
        pid_t rid = waitpid(id, NULL, 0);
        if (rid < 0) {
            perror("Error waiting for child process");
            return 3;
        }

        close(pipefd[0]); // 关闭读端
    }

    cout << "Program finished." << endl;
    return 0;
}

3.3 站在内核的角度

必须要调用 write read,系统调用,防止群众当中有坏人,操作系统起到了一个媒介的作用

note:

  • 混编C/C++需掌握字符串处理转换;
  • 管道通信需制定字节流数据协议。

编码实现

管道的 5 大特征

1. 具有血缘关系的进程,进行进程间通信

2. 管道只能单向通信

  • 为什么子进程休眠,父进程也会休眠?是的
  • 看到同一份资源实现了,多执行流共享,难免出现访问冲突的问题,存在临界资源竞争的问题

3. 管道是基于文件的,而文件的生命周期是随进程的例如:不需要我们去关 0 1 2

下面特性之后会详细解释:

4. 父子进程是会进程协同的,同步与互斥的---保护管道文件的数据安全

那父进程休眠,子进程呢?

不读的时候,一瞬间就把管道写满了,可以发现:管道是有固定大小的

5. 管道是面向字节流

可能写端写了十次一百次,读端都不管,看着就是一个一个字节的,上面提到管道有固定大小,那么是多少?

验证管道的固定大小: 使用 ulimit -a 命令可以查看当前用户进程的资源限制,其中包括管道的大小。管道大小在输出中通常标记为 pipe size

ulimit -a | grep "pipe size"
  1. 解释管道大小: 管道的默认大小在不同内核版本中可能有所不同。在许多 Linux 系统上,默认的管道大小是 64 KB。

查看 Linux 发行版和版本: 使用 cat /etc/redhat-release 命令可以查看 Red Hat 或 CentOS 系统的发行版和版本信息。

cat /etc/redhat-release

测试管道大小: 要测试管道大小是否为 64 KB,可以使用 dd 命令尝试写入一个大于 64 KB 的文件到管道,并观察是否能够成功写入。

dd if=/dev/zero of=/dev/null bs=65536 count=1 2>&1 | grep records

如果管道大小确实是 64 KB,那么上面的命令应该能成功写入 64 KB 数据。

查找 pipe_buf 大小pipe_buf 的大小定义在内核头文件中,可以通过查看内核源码或使用 grep 命令在内核头文件中搜索。制

grep -R "define PIPE_BUF" /usr/include/linux

或者,如果你有内核源码树,可以在源码中搜索:

grep -R "define PIPE_BUF" /path/to/linux-source-code/include/linux

进行原子性读取测试: 为了确保在不间断的情况下完整读取 “hello world” 字符串,并保证原子性,可以创建一个管道,并在一个进程中写入字符串,在另一个进程中读取。

管道的四种情况

  1. 读写段正常,管道如果为,读端就要阻塞
  2. 读写端正常,管道如果被写满,写端就要阻塞
  3. 读端正常读,写端关闭读端就会读到 0,表面读到了文件(pipe)结尾,不会被阻塞

eg. 父进程等待子进程(Z)退出,测试 n=0;

      4. 写端是正常写入,读端关闭了的情况呢?敬请期待下篇分解~

一些小思考:

1. 一个进程中可以开两个 pipe:

  • 一个进程可以创建多个管道,每个管道都有独立的读写端

2. read 读到文件尾,write 一写就会更新到文件头:

  • 管道是循环缓冲区,写入数据会覆盖最早的数据,read 指针会自动跳到新的数据开始处

3. 覆盖写,但为什么不会读取垃圾信息?read 指针也在移动:

  • 管道确保了写入和读取的原子性,每次读取都是连续的数据块,不会读取到被覆盖的旧数据。

拓展:

管道(pipe)是一种在进程间进行单向通信的机制。

为什么管道文件无法实现“写了就马上读到”:

  1. 缓冲区限制:管道有一个固定大小的缓冲区。当这个缓冲区满了之后,进一步的写操作将会被阻塞,直到有空间可用。这意味着,如果写入的数据超过了缓冲区的大小,那么这些数据不会立即被读取,因为它们还在等待空间变得可用
  2. 读写顺序:管道是按照顺序操作的。写入端(writer)必须先写入数据,然后读取端(reader)才能从管道中读取这些数据。如果读取端没有进行读取操作,写入端的数据可能会留在缓冲区中。
  3. 原子性:管道的读写操作具有原子性。这意味着每次读取操作要么读取一个完整的数据块,要么读取0个字节(如果缓冲区为空)。这防止了读取到不完整或“垃圾”数据。
  4. 阻塞与非阻塞:默认情况下,读取端如果尝试从一个空的管道中读取数据,将会被阻塞,直到有数据可读。
  5. 进程调度:操作系统的进程调度可能影响管道的读写操作。即使缓冲区中有数据,如果读取进程没有获得CPU时间,那么读取操作也不会发生。

总结来说,管道不是立即写入即读取的同步机制,而是一个提供了有序、缓冲的通信方式,其设计考虑了数据的完整性和进程间的同步。如果需要立即写入后读取,可能需要考虑其他通信机制,如消息队列或信号量。

本文地址:https://www.vps345.com/6225.html

搜索文章

Tags

PV计算 带宽计算 流量带宽 服务器带宽 上行带宽 上行速率 什么是上行带宽? CC攻击 攻击怎么办 流量攻击 DDOS攻击 服务器被攻击怎么办 源IP 服务器 linux 运维 游戏 云计算 javascript 前端 chrome edge ssh 阿里云 网络 网络安全 网络协议 llama 算法 opencv 自然语言处理 神经网络 语言模型 进程 操作系统 进程控制 Ubuntu ubuntu deepseek Ollama 模型联网 API CherryStudio python MCP RTSP xop RTP RTSPServer 推流 视频 harmonyos 华为 开发语言 typescript 计算机网络 数据库 centos oracle 关系型 安全 分布式 HCIE 数通 pycharm ide pytorch 人工智能 asm filezilla 无法连接服务器 连接被服务器拒绝 vsftpd 331/530 android 鸿蒙 tcp/ip numpy java 面试 性能优化 jdk intellij-idea 架构 c# GaN HEMT 氮化镓 单粒子烧毁 辐射损伤 辐照效应 Flask FastAPI Waitress Gunicorn uWSGI Uvicorn flutter Hyper-V WinRM TrustedHosts rust http macos adb udp unity ssl php 前端框架 宝塔面板访问不了 宝塔面板网站访问不了 宝塔面板怎么配置网站能访问 宝塔面板配置ip访问 宝塔面板配置域名访问教程 宝塔面板配置教程 Dell R750XS 科技 ai 个人开发 vue.js audio vue音乐播放器 vue播放音频文件 Audio音频播放器自定义样式 播放暂停进度条音量调节快进快退 自定义audio覆盖默认样式 uni-app 深度学习 YOLO 目标检测 计算机视觉 fastapi mcp mcp-proxy mcp-inspector fastapi-mcp agent sse vscode docker 容器 腾讯云 笔记 tomcat maven intellij idea 代码调试 ipdb Windsurf cuda cudnn anaconda 实时音视频 windows 微服务 springcloud nginx dubbo kubernetes VMware安装Ubuntu Ubuntu安装k8s k8s 嵌入式 linux驱动开发 arm开发 嵌入式硬件 智能路由器 外网访问 内网穿透 端口映射 word图片自动上传 word一键转存 复制word图片 复制word图文 复制word公式 粘贴word图文 粘贴word公式 僵尸进程 vim github git ansible 大模型 运维开发 Qwen2.5-coder 离线部署 kamailio sip VoIP 大数据 大数据平台 Linux 进程信号 websocket .net Dify rust腐蚀 pip conda 物联网 mcu iot 信息与通信 golang 后端 Ubuntu Server Ubuntu 22.04.5 gitlab c++ 多线程服务器 Linux网络编程 监控 自动化运维 pillow live555 rtsp rtp rabbitmq node.js json html5 firefox flask spring boot AI编程 AIGC WSL win11 无法解析服务器的名称或地址 firewalld https django web3.py 小程序 微信小程序域名配置 微信小程序服务器域名 微信小程序合法域名 小程序配置业务域名 微信小程序需要域名吗 微信小程序添加域名 web安全 Kali Linux 黑客 渗透测试 信息收集 redis mybatis vue3 HTML audio 控件组件 vue3 audio音乐播放器 Audio标签自定义样式默认 vue3播放音频文件音效音乐 自定义audio播放器样式 播放暂停调整声音大小下载文件 学习方法 经验分享 程序人生 efficientVIT YOLOv8替换主干网络 TOLOv8 jenkins gitee transformer ffmpeg 音视频 创意 社区 DeepSeek-R1 API接口 源码剖析 rtsp实现步骤 流媒体开发 远程控制 远程看看 远程协助 WSL2 单片机 温湿度数据上传到服务器 Arduino HTTP cpu 内存 实时 使用 开源 C语言 YOLOv12 学习 DigitalOcean GPU服务器购买 GPU服务器哪里有 GPU服务器 apache YOLOv8 NPU Atlas800 A300I pro asi_bench 博客 mount挂载磁盘 wrong fs type LVM挂载磁盘 Centos7.9 fpga开发 统信UOS 麒麟 bonding 链路聚合 计算机外设 电脑 mac 软件需求 安装教程 GPU环境配置 Ubuntu22 CUDA PyTorch Anaconda安装 c语言 qt stm32项目 stm32 mongodb debian PVE 华为云 .netcore 微信 微信分享 Image wxopensdk 产品经理 agi microsoft react.js 前端面试题 持续部署 ollama下载加速 oceanbase rc.local 开机自启 systemd 爬虫 数据挖掘 网络用户购物行为分析可视化平台 大数据毕业设计 1024程序员节 chatgpt llama3 Chatglm 开源大模型 ping++ 机器学习 深度优先 图论 并集查找 换根法 树上倍增 ddos ollama llm 数据结构 gpu算力 低代码 HarmonyOS Next zotero WebDAV 同步失败 代理模式 自动化 蓝耘科技 元生代平台工作流 ComfyUI jmeter 软件测试 命名管道 客户端与服务端通信 银河麒麟服务器操作系统 系统激活 gateway Clion Nova ResharperC++引擎 Centos7 远程开发 sql KingBase sqlserver 负载均衡 C 环境变量 进程地址空间 AI Agent ESP32 智能手机 NAS Termux Samba 豆瓣 追剧助手 迅雷 nas postman mock mock server 模拟服务器 mock服务器 Postman内置变量 Postman随机数据 LDAP mysql aws googlecloud Reactor 设计模式 C++ IIS服务器 IIS性能 日志监控 能力提升 面试宝典 技术 IT信息化 ESXi nvidia rpc ip命令 新增网卡 新增IP 启动网卡 nuxt3 matlab 边缘计算 智能硬件 软件工程 华为od dify sqlite MS Materials openssl 密码学 DNS 业界资讯 mysql离线安装 ubuntu22.04 mysql8.0 模拟退火算法 spring cloud 源码 毕业设计 课程设计 code-server MQTT mosquitto 消息队列 混合开发 环境安装 JDK postgresql r语言 数据可视化 数据分析 云原生 DevEco Studio 系统架构 计算机 程序员 LLM AI大模型 C# MQTTS 双向认证 emqx 命令行 基础入门 编程 kafka hibernate sqlite3 CLion 远程连接 IDE threejs 3D echarts 信息可视化 网页设计 centos-root /dev/mapper yum clean all df -h / du -sh jar gradle shell 数据库系统 京东云 spring 串口服务器 大模型入门 Deepseek 大模型教程 curl wget remote-ssh 缓存 国产操作系统 ukui 麒麟kylinos openeuler 统信 虚拟机安装 框架搭建 docker run 数据卷挂载 交互模式 kind openEuler linux 命令 sed 命令 企业微信 Linux24.04 deepin 集成学习 集成测试 火绒安全 云服务器 VPS zabbix Nuxt.js devops springboot 技能大赛 设置代理 实用教程 iBMC UltraISO 其他 微信小程序 RTMP 应用层 jupyter camera Arduino 电子信息 virtualenv linux环境变量 ragflow express okhttp CORS 跨域 bash 雨云 NPS 远程工作 孤岛惊魂4 uniapp vue 飞牛NAS 飞牛OS MacBook Pro 恒源云 cnn eNSP 网络规划 VLAN 企业网络 vSphere vCenter 软件定义数据中心 sddc IPMITOOL BMC 硬件管理 opcua opcda KEPServer安装 oneapi 数据库架构 数据管理 数据治理 数据编织 数据虚拟化 prometheus k8s资源监控 annotations自动化 自动化监控 监控service 监控jvm 大模型微调 open webui idm 传统数据库升级 银行 大语言模型 LLMs VSCode 华为认证 网络工程师 交换机 NFS Docker Compose docker compose docker-compose 移动云 android studio 鲲鹏 FTP 服务器 pdf 指令 mariadb mq rocketmq 服务器数据恢复 数据恢复 存储数据恢复 raid5数据恢复 磁盘阵列数据恢复 iftop 网络流量监控 webrtc visualstudio make命令 makefile文件 netty TRAE 部署 SSL 域名 Anolis nginx安装 linux插件下载 驱动开发 Linux awk awk函数 awk结构 awk内置变量 awk参数 awk脚本 awk详解 鸿蒙系统 DeepSeek 服务器繁忙 安卓 Trae AI 原生集成开发环境 Trae AI 3d 测试工具 状态管理的 UDP 服务器 Arduino RTOS 机器人 硬件工程 嵌入式实习 RustDesk自建服务器 rustdesk服务器 docker rustdesk 黑客技术 Docker Hub docker pull 镜像源 daemon.json 流式接口 URL 本地部署 api web ceph pyqt java-ee 监控k8s 监控kubernetes Kylin-Server 服务器安装 EasyConnect Cline ecmascript nextjs react reactjs 文件系统 路径解析 WebUI DeepSeek V3 visual studio code hadoop 网工 opensearch helm 深度求索 私域 知识库 搜索引擎 ssrf 失效的访问控制 WebRTC gpt openwrt 并查集 leetcode SysBench 基准测试 ux 多线程 open Euler dde Python 网络编程 聊天服务器 套接字 TCP 客户端 Socket 腾讯云大模型知识引擎 QQ bot Docker RAGFLOW RAG 检索增强生成 文档解析 大模型垂直应用 xrdp 远程桌面 string模拟实现 深拷贝 浅拷贝 经典的string类问题 三个swap 游戏服务器 TrinityCore 魔兽世界 adobe elk 交互 群晖 文件分享 中间件 iis 雨云服务器 报错 springsecurity6 oauth2 授权服务器 token sas 编辑器 环境迁移 服务器管理 宝塔面板 配置教程 网站管理 Dell HPE 联想 浪潮 崖山数据库 YashanDB 医疗APP开发 app开发 Ubuntu 24.04.1 轻量级服务器 redhat 系统安全 毕设 相差8小时 UTC 时间 Java 命令 JAVA 图像处理 asp.net大文件上传 asp.net大文件上传源码 ASP.NET断点续传 asp.net上传文件夹 asp.net上传大文件 .net core断点续传 .net mvc断点续传 kylin 银河麒麟操作系统 国产化 远程过程调用 Windows环境 监控k8s集群 集群内prometheus 直播推流 服务器部署ai模型 rsyslog svn playbook 剧本 kvm 无桌面 k8s集群资源管理 云原生开发 媒体 微信公众平台 protobuf 序列化和反序列化 安装 risc-v kali 共享文件夹 虚拟机 webstorm ipython ros2 moveit 机器人运动 强制清理 强制删除 mac废纸篓 Ubuntu 24 常用命令 Ubuntu 24 Ubuntu vi 异常处理 eureka html css 工业4.0 联想开天P90Z装win10 ai小智 语音助手 ai小智配网 ai小智教程 esp32语音助手 diy语音助手 游戏程序 ios RoboVLM 通用机器人策略 VLA设计哲学 vlm fot robot 视觉语言动作模型 具身智能 bootstrap ci/cd pygame 压力测试 CPU 主板 电源 网卡 Ark-TS语言 telnet 远程登录 ecm bpm 压测 ECS selenium 网站搭建 serv00 宕机切换 服务器宕机 灵办AI 微信开放平台 微信公众号配置 VMware wireshark 显示过滤器 ICMP Wireshark安装 图形化界面 minicom 串口调试工具 Minecraft rime cmos 硬件 iDRAC R720xd SWAT 配置文件 服务管理 网络共享 wsl2 wsl VMware安装mocOS macOS系统安装 GCC crosstool-ng thingsboard unix 磁盘监控 gcc docker命令大全 5G 3GPP 卫星通信 dell服务器 go 硬件架构 虚拟化 半虚拟化 硬件虚拟化 Hypervisor IIS .net core Hosting Bundle .NET Framework vs2022 多层架构 解耦 XFS xfs文件系统损坏 I_O error es jvm micropython esp32 mqtt file server http server web server yum 服务器配置 生物信息学 分析解读 pgpool 系统开发 binder 车载系统 framework 源码环境 gitea 田俊楠 政务 分布式系统 监控运维 Prometheus Grafana Invalid Host allowedHosts rdp 实验 selete 高级IO Linux PID 王者荣耀 minio 大模型面经 职场和发展 大模型学习 W5500 OLED u8g2 TCP服务器 jetty undertow chfs ubuntu 16.04 MacMini Mac 迷你主机 mini Apple UOS 统信操作系统 宠物 免费学习 宠物领养 宠物平台 tcpdump 小艺 Pura X excel 设备 GPU PCI-Express MNN Qwen ip ui bug 音乐服务器 Navidrome 音流 etcd 数据安全 RBAC 网络穿透 Erlang OTP gen_server 热代码交换 事务语义 Ubuntu DeepSeek DeepSeek Ubuntu DeepSeek 本地部署 DeepSeek 知识库 DeepSeek 私有化知识库 本地部署 DeepSeek DeepSeek 私有化部署 金融 SSH 服务 SSH Server OpenSSH Server freebsd hugo VR手套 数据手套 动捕手套 动捕数据手套 OD机试真题 华为OD机试真题 服务器能耗统计 ruoyi 蓝桥杯 MQTT协议 消息服务器 代码 DeepSeek行业应用 Heroku 网站部署 AI写作 AI作画 next.js 部署next.js 聊天室 Playwright 自动化测试 输入法 av1 电视盒子 机顶盒ROM 魔百盒刷机 思科模拟器 思科 Cisco 数学建模 北亚数据恢复 oracle数据恢复 linux上传下载 docker搭建nacos详解 docker部署nacos docker安装nacos 腾讯云搭建nacos centos7搭建nacos 测试用例 功能测试 springboot远程调试 java项目远程debug docker远程debug java项目远程调试 springboot远程 muduo X11 Xming vmware 卡死 RAID RAID技术 磁盘 存储 XCC Lenovo 远程 执行 sshpass 操作 繁忙 解决办法 替代网站 汇总推荐 AI推理 dba Redis Desktop chrome devtools chromedriver list skynet 弹性计算 KVM 计算虚拟化 弹性裸金属 ArcTS 登录 ArcUI GridItem 多进程 arkUI AI代码编辑器 向日葵 windwos防火墙 defender防火墙 win防火墙白名单 防火墙白名单效果 防火墙只允许指定应用上网 防火墙允许指定上网其它禁止 embedding 安全威胁分析 vscode 1.86 Cursor Linux无人智慧超市 LInux多线程服务器 QT项目 LInux项目 单片机项目 grafana 直流充电桩 充电桩 IPMI 漏洞 unity3d 银河麒麟 kylin v10 麒麟 v10 safari 系统 SSH Xterminal 裸金属服务器 弹性裸金属服务器 p2p elasticsearch Portainer搭建 Portainer使用 Portainer使用详解 Portainer详解 Portainer portainer ue4 着色器 ue5 虚幻 目标跟踪 OpenVINO 推理应用 Netty 即时通信 NIO 数据集 小游戏 五子棋 开机自启动 sdkman Google pay Apple pay 服务器主板 AI芯片 c/c++ 串口 vpn 语音识别 AutoDL alias unalias 别名 Logstash 日志采集 figma WSL2 上安装 Ubuntu mamba Vmamba vasp安装 查询数据库服务IP地址 SQL Server VMware创建虚拟机 宝塔 qt项目 qt项目实战 qt教程 tidb GLIBC 用户缓冲区 模拟实现 EtherNet/IP串口网关 EIP转RS485 EIP转Modbus EtherNet/IP网关协议 EIP转RS485网关 EIP串口服务器 国标28181 视频监控 监控接入 语音广播 流程 SIP SDP GoogLeNet DeepSeek r1 Open WebUI 支付 微信支付 开放平台 ArkTs ArkUI regedit 开机启动 云服务 视觉检测 wordpress 无法访问wordpess后台 打开网站页面错乱 linux宝塔面板 wordpress更换服务器 OpenManus fd 文件描述符 eclipse 游戏引擎 NLP模型 NLP AISphereButler 自学笔记 小米 澎湃OS Android Mac内存不够用怎么办 prompt hive Hive环境搭建 hive3环境 Hive远程模式 webgl miniapp 真机调试 调试 debug 断点 网络API请求调试方法 cocoapods xcode 银河麒麟高级服务器 外接硬盘 Kylin ruby Node-Red 编程工具 流编程 实时互动 根服务器 考研 华为机试 SenseVoice 版本 flash-attention 做raid 装系统 Java Applet URL操作 服务器建立 Socket编程 网络文件读取 可信计算技术 安全架构 网络攻击模型 yolov8 bat 大模型应用 Kali 渗透 OpenSSH 升级 CVE-2024-7347 RAGFlow 本地知识库部署 DeepSeek R1 模型 frp 内网服务器 内网代理 内网通信 EtherCAT转Modbus ECT转Modbus协议 EtherCAT转485网关 ECT转Modbus串口网关 EtherCAT转485协议 ECT转Modbus网关 VM搭建win2012 win2012应急响应靶机搭建 攻击者获取服务器权限 上传wakaung病毒 应急响应并溯源 挖矿病毒处置 应急响应综合性靶场 需求分析 规格说明书 epoll 架构与原理 IPv4 子网掩码 公网IP 私有IP Ubuntu22.04 开发人员主页 反向代理 trea idea big data IDEA 相机 权限 飞书 Cookie 移动魔百盒 web3 USB转串口 CH340 自动化任务管理 tcp easyui langchain 邮件APP 免费软件 单一职责原则 线程 aarch64 编译安装 HPC 飞牛nas fnos log4j yum源切换 更换国内yum源 lua vue-i18n 国际化多语言 vue2中英文切换详细教程 如何动态加载i18n语言包 把语言json放到服务器调用 前端调用api获取语言配置文件 vr 键盘 spark HistoryServer Spark YARN jobhistory 性能测试 Headless Linux 音乐库 飞牛 glibc 链表 文心一言 asp.net大文件上传下载 iphone sentinel 自定义客户端 SAS nac 802.1 portal 僵尸世界大战 游戏服务器搭建 midjourney zookeeper AP配网 AK配网 小程序AP配网和AK配网教程 WIFI设备配网小程序UDP开 nfs 免费域名 域名解析 AI-native Docker Desktop 大大通 第三代半导体 碳化硅 回显服务器 UDP的API使用 Linux的权限 Windows ai工具 办公自动化 自动化生成 pdf教程 v10 软件 ldap armbian u-boot GIS 遥感 WebGIS npm 网络结构图 yaml Ultralytics 可视化 无人机 ROS 自动驾驶 项目部署到linux服务器 项目部署过程 ftp 干货分享 黑客工具 密码爆破 banner g++ g++13 技术共享 Linux环境 远程服务 arcgis LLM Web APP Streamlit MacOS录屏软件 运维监控 cpp-httplib x64 SIGSEGV SSE xmm0 稳定性 看门狗 MI300x 执法记录仪 智能安全帽 smarteye Typore pyautogui vscode1.86 1.86版本 ssh远程连接 信号处理 迁移指南 流水线 脚本式流水线 DenseNet CrewAI SRS 流媒体 直播 匿名管道 代理 单例模式 开发环境 SSL证书 qemu libvirt sysctl.conf vm.nr_hugepages 串口驱动 CH341 uart 485 WebVM Linux的基础指令 bcompare Beyond Compare 交叉编译 模拟器 教程 odoo 服务器动作 Server action 视频编解码 dash 正则表达式 cd 目录切换 UOS1070e tensorflow 昇腾 npu 代码托管服务 网络药理学 生信 gromacs 分子动力学模拟 MD 动力学模拟 apt 国内源 高效日志打印 串口通信日志 服务器日志 系统状态监控日志 异常记录日志 嵌入式Linux IPC uni-file-picker 拍摄从相册选择 uni.uploadFile H5上传图片 微信小程序上传图片 自动化编程 矩阵 swoole 三级等保 服务器审计日志备份 EMUI 回退 降级 FTP服务器 linux安装配置 arm ubuntu24.04.1 软考 VS Code deep learning IO模型 lsb_release /etc/issue /proc/version uname -r 查看ubuntu版本 多个客户端访问 IO多路复用 TCP相关API c 游戏开发 tailscale derp derper 中转 triton 模型分析 线性代数 电商平台 大文件分片上传断点续传及进度条 如何批量上传超大文件并显示进度 axios大文件切片上传详细教 node服务器合并切片 vue3大文件上传报错提示错误 大文件秒传跨域报错cors 单元测试 互信 小智AI服务端 xiaozhi ASR TTS C++软件实战问题排查经验分享 0xfeeefeee 0xcdcdcdcd 动态库加载失败 程序启动失败 程序运行权限 标准用户权限与管理员权限 n8n 工作流 workflow powerpoint AD 域管理 上传视频至服务器代码 vue3批量上传多个视频并预览 如何实现将本地视频上传到网页 element plu视频上传 ant design vue vue3本地上传视频及预览移除 dity make xml cursor 磁盘镜像 服务器镜像 服务器实时复制 实时文件备份 MCP server C/S windows日志 软件构建 实战案例 edge浏览器 虚拟显示器 DOIT 四博智联 Unity Dedicated Server Host Client 无头主机 H3C ros cfssl 重启 排查 系统重启 日志 原因 IMX317 MIPI H265 VCU trae 毕昇JDK 常用命令 文本命令 目录命令 python3.11 我的世界服务器搭建 minecraft 安防软件 firewall 端口测试 Ubuntu共享文件夹 共享目录 Linux共享文件夹 前后端分离 分布式训练 DocFlow 服务器无法访问 ip地址无法访问 无法访问宝塔面板 宝塔面板打不开 TrueLicense 英语 怎么卸载MySQL MySQL怎么卸载干净 MySQL卸载重新安装教程 MySQL5.7卸载 Linux卸载MySQL8.0 如何卸载MySQL教程 MySQL卸载与安装 Jellyfin FunASR 聚类 佛山戴尔服务器维修 佛山三水服务器维修 LInux Spring Security 我的世界 我的世界联机 数码 信号 策略模式 clickhouse outlook 虚拟局域网 Wi-Fi 超融合 本地部署AI大模型 强化学习 显卡驱动 AnythingLLM AnythingLLM安装 ISO镜像作为本地源 gpt-3 云电竞 云电脑 todesk Claude 备份SQL Server数据库 数据库备份 傲梅企业备份网络版 rustdesk 基础环境 序列化反序列化 DIFY 主从复制 人工智能生成内容 ocr seleium pppoe radius 程序员创富 致远OA OA服务器 服务器磁盘扩容 gaussdb can 线程池 dns是什么 如何设置电脑dns dns应该如何设置 xss 在线预览 xlsx xls文件 在浏览器直接打开解析xls表格 前端实现vue3打开excel 文件地址url或接口文档流二进 dns 7z USB网络共享 推荐算法 P2P HDLC HarmonyOS AI agent IM即时通讯 剪切板对通 HTML FORMAT 双系统 GRUB引导 Linux技巧 saltstack keepalived lio-sam SLAM sonoma 自动更新 uv CDN xshell termius iterm2 算力 neo4j 数据仓库 数据库开发 database ssh漏洞 ssh9.9p2 CVE-2025-23419 阿里云ECS Radius 高效远程协作 TrustViewer体验 跨设备操作便利 智能远程控制 rclone AList webdav fnOS EMQX 通信协议 flink 软负载 服务网格 istio wps etl 社交电子 rnn 同步 备份 建站 阻塞队列 生产者消费者模型 服务器崩坏原因 matplotlib laravel less junit 小番茄C盘清理 便捷易用C盘清理工具 小番茄C盘清理的优势尽显何处? 教你深度体验小番茄C盘清理 C盘变红?!不知所措? C盘瘦身后电脑会发生什么变化? 读写锁 LORA 显示管理器 lightdm gdm Docker引擎已经停止 Docker无法使用 WSL进度一直是0 镜像加速地址 语法 seatunnel perf 影刀 #影刀RPA# DBeaver kerberos 历史版本 下载 k8s二次开发 集群管理 捆绑 链接 谷歌浏览器 youtube google gmail openstack Xen 游戏机 图形渲染 实习 黑苹果 HTTP 服务器控制 ESP32 DeepSeek composer rag ragflow 源码启动 备选 网站 调用 示例 银河麒麟桌面操作系统 Kylin OS 产测工具框架 IMX6ULL 管理框架 AD域 钉钉 信创 信创终端 中科方德 端口聚合 windows11 prometheus数据采集 prometheus数据模型 prometheus特点 milvus 抓包工具 System V共享内存 进程通信 db 软链接 硬链接 程序 性能分析 SVN Server tortoise svn PX4 MacOS 网络建设与运维 HAProxy HiCar CarLife+ CarPlay QT RK3588 本地化部署 进程优先级 调度队列 进程切换 docker desktop image onlyoffice 在线office 端口 查看 ss chrome 浏览器下载 chrome 下载安装 谷歌浏览器下载 私有化 玩机技巧 软件分享 软件图标 SSH 密钥生成 SSH 公钥 私钥 生成 kernel word MySql docker部署翻译组件 docker部署deepl docker搭建deepl java对接deepl 翻译组件使用 nlp iperf3 带宽测试 KylinV10 麒麟操作系统 Vmware su sudo 环境配置 ShenTong harmonyOS面试题 autodl Deepseek-R1 私有化部署 推理模型 IMM 欧标 OCPP 树莓派 VNC deepseek r1 Xinference 域名服务 DHCP 符号链接 配置 wpf 代理服务器 Qwen2.5-VL vllm 健康医疗 互联网医院 粘包问题 嵌入式系统开发 极限编程 java-rocketmq perl 李心怡 镜像 nosql 加解密 Yakit yaklang docker部署Python MDK 嵌入式开发工具 论文笔记 sublime text 内网环境 h.264 navicat WLAN 网卡的名称修改 eth0 ens33 rpa win服务器架设 windows server Attention 流量运营 大模型部署 zip unzip 网络爬虫 查看显卡进程 fuser ArtTS Linux find grep jina llama.cpp 增强现实 沉浸式体验 应用场景 技术实现 案例分析 AR nvm whistle 虚幻引擎 virtualbox CentOS 问题解决 ubuntu24 vivado24 开发 知识图谱 区块链 kotlin 状态模式 gnu xpath定位元素 Sealos rancher 烟花代码 烟花 元旦 性能调优 安全代理 中兴光猫 换光猫 网络桥接 自己换光猫 visual studio rtsp服务器 rtsp server android rtsp服务 安卓rtsp服务器 移动端rtsp服务 大牛直播SDK 多端开发 智慧分发 应用生态 鸿蒙OS hexo fast hosts ranger MySQL8.0 grub 版本升级 扩容 网络搭建 神州数码 神州数码云平台 云平台 换源 Debian ip协议 searxng PPI String Cytoscape CytoHubba 防火墙 NAT转发 NAT Server 元服务 应用上架 金仓数据库 2025 征文 数据库平替用金仓 抗锯齿 沙盒 deekseek Unity插件 HarmonyOS NEXT 原生鸿蒙 iventoy VmWare OpenEuler css3 计算生物学 生物信息 基因组 云桌面 微软 AD域控 证书服务器 fstab MVS 海康威视相机 浏览器自动化 Python基础 Python教程 Python技巧 UDP proxy模式 top Linux top top命令详解 top命令重点 top常用参数 ubuntu20.04 ros1 Noetic 20.04 apt 安装 ABAP react native 服务器时间 磁盘清理 存储维护 NetApp存储 EMC存储 带外管理 大模型推理 CentOS Stream 容器技术 vu大文件秒传跨域报错cors 企业网络规划 华为eNSP docker搭建pg docker搭建pgsql pg授权 postgresql使用 postgresql搭建 多路转接 对比 工具 meld DiffMerge ssh远程登录 智能音箱 智能家居 QT 5.12.12 QT开发环境 Ubuntu18.04 个人博客 项目部署 浏览器开发 AI浏览器 wsgiref Web 服务器网关接口 云耀服务器 物联网开发 软件卸载 系统清理 deployment daemonset statefulset cronjob 合成模型 扩散模型 图像生成 SEO 上传视频文件到服务器 uniApp本地上传视频并预览 uniapp移动端h5网页 uniapp微信小程序上传视频 uniapp app端视频上传 uniapp uview组件库 ardunio BLE AI Agent 字节智能运维 Linux权限 权限命令 特殊权限 OpenHarmony 鸿蒙开发 移动开发 TCP协议 拓扑图 sequoiaDB 达梦 DM8 数字证书 签署证书 智能电视 搭建个人相关服务器 接口优化 AI员工 服务器正确解析请求体 MAVROS 四旋翼无人机 IO 解决方案 openvpn server openvpn配置教程 centos安装openvpn 安装MySQL 通信工程 毕业 conda配置 conda镜像源 vnc MobaXterm yum换源 电视剧收视率分析与可视化平台 论文阅读 centos 7 macOS mm-wiki搭建 linux搭建mm-wiki mm-wiki搭建与使用 mm-wiki使用 mm-wiki详解 开机黑屏 像素流送api 像素流送UE4 像素流送卡顿 像素流送并发支持 ubuntu 18.04 dock 加速 搜狗输入法 中文输入法 风扇控制软件 热榜 离线部署dify 西门子PLC 通讯 虚拟现实 yolov5 js